【发布时间】:2013-10-18 23:44:38
【问题描述】:
我有 python TCP 客户端,需要循环发送媒体(.mpg)文件到“C”TCP 服务器。
我有以下代码,在单独的线程中,我正在读取 10K 文件块并将其发送并在循环中重新执行,我认为这是因为我实现了线程模块或 tcp send . 我正在使用 Queues 在我的 GUI (Tkinter) 上打印日志,但过了一段时间它内存不足。。
更新 1 - 根据要求添加了更多代码
线程类“Sendmpgthread”用于创建线程发送数据
.
.
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
【问题讨论】:
-
为什么你'需要循环运行它'?需求不应该规定这样的微小细节。除非您处于非阻塞模式,否则一次发送将花费整个过程。
-
服务器选择文件并播放它,它需要循环播放,我无法将文件发送到服务器并让它从那里播放,因为我们已经逆向工程了完整的 linux 内核和媒体从客户端控制播放器
-
你能注释掉调用self.printlog(msg),看看问题是在实际队列中还是在打印日志中?
-
如果你不断地调用 self.edit.insert 那么编辑控件使用的内存会一直增长。但是没必要去猜测,直接注释掉看看会发生什么。内存泄漏通常并不意味着函数“不起作用”,而是某个地方正在“积累内存”
-
控制台将只显示最后的 X 日志消息,您可以对编辑控件执行相同操作。我会为此添加一个答案,因为 cmets 不是最好的地方。您还应该更新提及 tkinter self.edit.insert 调用的问题
标签: python multithreading python-2.7 memory-leaks queue