<legend id='G7ma2'><style id='G7ma2'><dir id='G7ma2'><q id='G7ma2'></q></dir></style></legend>

  • <small id='G7ma2'></small><noframes id='G7ma2'>

    <i id='G7ma2'><tr id='G7ma2'><dt id='G7ma2'><q id='G7ma2'><span id='G7ma2'><b id='G7ma2'><form id='G7ma2'><ins id='G7ma2'></ins><ul id='G7ma2'></ul><sub id='G7ma2'></sub></form><legend id='G7ma2'></legend><bdo id='G7ma2'><pre id='G7ma2'><center id='G7ma2'></center></pre></bdo></b><th id='G7ma2'></th></span></q></dt></tr></i><div id='G7ma2'><tfoot id='G7ma2'></tfoot><dl id='G7ma2'><fieldset id='G7ma2'></fieldset></dl></div>

          <bdo id='G7ma2'></bdo><ul id='G7ma2'></ul>

        <tfoot id='G7ma2'></tfoot>

        在线程内调用时,Python Queues 内存泄漏

        时间:2023-09-29
          <tbody id='YPLdi'></tbody>
      1. <small id='YPLdi'></small><noframes id='YPLdi'>

            <bdo id='YPLdi'></bdo><ul id='YPLdi'></ul>
            • <legend id='YPLdi'><style id='YPLdi'><dir id='YPLdi'><q id='YPLdi'></q></dir></style></legend>
            • <i id='YPLdi'><tr id='YPLdi'><dt id='YPLdi'><q id='YPLdi'><span id='YPLdi'><b id='YPLdi'><form id='YPLdi'><ins id='YPLdi'></ins><ul id='YPLdi'></ul><sub id='YPLdi'></sub></form><legend id='YPLdi'></legend><bdo id='YPLdi'><pre id='YPLdi'><center id='YPLdi'></center></pre></bdo></b><th id='YPLdi'></th></span></q></dt></tr></i><div id='YPLdi'><tfoot id='YPLdi'></tfoot><dl id='YPLdi'><fieldset id='YPLdi'></fieldset></dl></div>
                <tfoot id='YPLdi'></tfoot>

                1. 本文介绍了在线程内调用时,Python Queues 内存泄漏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                  问题描述

                  我有 python TCP 客户端,需要循环发送媒体(.mpg)文件到C"TCP 服务器.

                  I have python TCP client and need to send media(.mpg) file in a loop to a 'C' TCP server.

                  我有以下代码,在单独的线程中,我正在读取 10K 文件块并将其发送并在循环中重新执行,我认为这是因为我实现了线程模块或 tcp send. 我正在使用 Queues 在我的 GUI (Tkinter) 上打印日志,但过了一段时间它内存不足..

                  I have following code, where in separate thread I am reading the 10K blocks of file and sending it and doing it all over again in loop, I think it is because of my implementation of thread module, or tcp send. I am using Queues to print the logs on my GUI ( Tkinter ) but after some times it goes out of memory..

                  更新 1 - 根据要求添加了更多代码

                  线程类Sendmpgthread"用于创建线程发送数据

                  Thread class "Sendmpgthread" used to create thread to send data

                  .
                  . 
                  def __init__ ( self, otherparams,MainGUI):
                      .
                      .
                      self.MainGUI = MainGUI
                      self.lock = threading.Lock()
                      Thread.__init__(self)
                  
                  #This is the one causing leak, this is called inside loop
                  def pushlog(self,msg):
                      self.MainGUI.queuelog.put(msg)
                  
                  def send(self, mysocket, block):
                      size = len(block)
                      pos = 0;
                      while size > 0:
                          try:
                              curpos = mysocket.send(block[pos:])
                          except socket.timeout, msg:
                              if self.over:
                                   self.pushlog(Exit Send)
                                  return False
                          except socket.error, msg:
                              print 'Exception'     
                              return False  
                          pos = pos + curpos
                          size = size - curpos
                      return True
                  
                  def run(self):
                      media_file = None
                      mysocket = None 
                  
                      try:
                          mysocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                          mysocket.connect((self.ip, string.atoi(self.port)))
                          media_file = open(self.file, 'rb') 
                  
                          while not self.over:
                              chunk = media_file.read(10000)
                              if not chunk:   # EOF Reset it
                                  print 'resetting stream'
                                  media_file.seek(0, 0)
                                  continue
                              if not self.send(mysocket, chunk): # If some error or thread is killed 
                                  break;
                  
                              #disabling this solves the issue
                              self.pushlog('print how much data sent')       
                  
                      except socket.error, msg:
                          print 'print exception'
                      except Exception, msg:
                          print 'print exception'
                  
                      try:
                          if media_file is not None:
                              media_file.close()
                              media_file = None            
                          if mysocket is not None:
                              mysocket.close()
                              mysocket = None
                      finally:
                              print 'some cleaning'   
                  
                  def kill(self):
                      self.over = True
                  

                  我发现这是因为 Queue 的错误实现,因为评论该部分解决了问题

                  更新 2 - 从 Thread 类调用的 MainGUI 类

                  class MainGUI(Frame):
                      def __init__(self, other args):
                         #some code
                         .
                         .
                          #from the above thread class used to send data
                          self.send_mpg_status = Sendmpgthread(params)
                          self.send_mpg_status.start()     
                          self.after(100, self.updatelog)
                          self.queuelog = Queue.Queue()
                  
                      def updatelog(self):
                         try:
                             msg = self.queuelog.get_nowait() 
                  
                             while msg is not None:
                                 self.printlog(msg)
                                 msg = self.queuelog.get_nowait() 
                          except Queue.Empty:
                             pass
                  
                          if self.send_mpg_status: # only continue when sending   
                              self.after(100, self.updatelog)
                  
                      def printlog(self,msg):
                          #print in GUI
                  

                  推荐答案

                  由于 printlog 正在添加到 tkinter 文本控件,该控件占用的内存将随着每条消息而增长(它必须存储所有日志消息才能显示它们).

                  Since printlog is adding to a tkinter text control, the memory occupied by that control will grow with each message (it has to store all the log messages in order to display them).

                  除非存储所有日志至关重要,否则一个常见的解决方案是限制显示的最大日志行数.

                  Unless storing all the logs is critical, a common solution is to limit the maximum number of log lines displayed.

                  一个简单的实现是在控件达到最大消息数后从一开始就消除多余的行.添加一个函数获取控件的行数 然后,在 printlog 中类似于:

                  A naive implementation is to eliminate extra lines from the begining after the control reaches a maximum number of messages. Add a function to get the number of lines in the control and then, in printlog something similar to:

                  while getnumlines(self.edit) > self.maxloglines:
                      self.edit.delete('1.0', '1.end')
                  

                  (以上代码未测试)

                  更新:一些一般准则

                  请记住,看起来像内存泄漏的情况并不总是意味着函数错误,或者内存不再可访问.很多时候,正在积累元素的容器缺少清理代码.

                  Keep in mind that what might look like a memory leak does not always mean that a function is wrong, or that the memory is no longer accessible. Many times there is missing cleanup code for a container that is accumulating elements.

                  此类问题的基本通用方法:

                  A basic general approach for this kind of problems:

                  • 就代码的哪一部分可能导致问题形成意见
                  • 通过注释掉该代码来检查它(或继续注释代码直到找到候选人)
                  • 在负责的代码中查找容器,添加代码以打印其大小
                  • 决定哪些元素可以安全地从容器中移除,以及何时移除
                  • 测试结果

                  这篇关于在线程内调用时,Python Queues 内存泄漏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                  上一篇:双端队列在 Python 中是如何工作的 下一篇:我可以从 PriorityQueue 中获取项目而不删除它吗?

                  相关文章

                  <i id='8W0Jz'><tr id='8W0Jz'><dt id='8W0Jz'><q id='8W0Jz'><span id='8W0Jz'><b id='8W0Jz'><form id='8W0Jz'><ins id='8W0Jz'></ins><ul id='8W0Jz'></ul><sub id='8W0Jz'></sub></form><legend id='8W0Jz'></legend><bdo id='8W0Jz'><pre id='8W0Jz'><center id='8W0Jz'></center></pre></bdo></b><th id='8W0Jz'></th></span></q></dt></tr></i><div id='8W0Jz'><tfoot id='8W0Jz'></tfoot><dl id='8W0Jz'><fieldset id='8W0Jz'></fieldset></dl></div>
                  <tfoot id='8W0Jz'></tfoot>

                  <legend id='8W0Jz'><style id='8W0Jz'><dir id='8W0Jz'><q id='8W0Jz'></q></dir></style></legend>

                2. <small id='8W0Jz'></small><noframes id='8W0Jz'>

                  • <bdo id='8W0Jz'></bdo><ul id='8W0Jz'></ul>