【发布时间】:2014-05-01 20:06:43
【问题描述】:
我正在做类似于this question 的事情,但有一个更微妙的问题。
我有一个发出 HTTP 请求的 API 客户端类;我将 QNetworkReply 存储在对象中,以便从连接到“完成”信号的插槽访问其数据。在下一个请求中,这将被下一个 QNetworkReply 替换,因此 Python 应该能够释放前一个请求对象,从而释放底层网络资源。相反,旧的回复对象似乎卡在某个地方,导致内存泄漏,如果应用运行时间足够长,退出延迟,大概是因为所有发出的请求最终都被删除了。
简单但完整的例子:
import sys, signal
from PySide import QtCore, QtNetwork
class Poller(QtCore.QObject):
url = QtCore.QUrl("http://localhost:5000/")
def __init__(self, parent=None):
super(Poller,self).__init__(parent)
self.manager = QtNetwork.QNetworkAccessManager()
def start(self):
request = QtNetwork.QNetworkRequest(self.url)
self.reply = self.manager.get(request)
self.reply.finished.connect(self.readReply)
self.reply.error.connect(self.error)
def readReply(self):
text = self.reply.readAll()
self.reply.close() # doesn't help
self.reply.deleteLater() # doesn't help
QtCore.QTimer.singleShot(10, self.start)
@QtCore.Slot(QtNetwork.QNetworkReply.NetworkError)
def error(self, err):
self.reply.finished.disconnect()
sys.stderr.write('Error: ' + str(err) + '\n')
QtCore.QTimer.singleShot(10, self.start)
signal.signal(signal.SIGINT, signal.SIG_DFL)
app = QtCore.QCoreApplication(sys.argv)
p = Poller()
p.start()
app.exec_()
被轮询的 http 服务器无关紧要;对于这个测试,我使用the Flask hello world。事实上,由于这不会进行连接保持活动,如果我检查“netstat”,我会看到处于 TIME_WAIT 状态的僵尸 TCP 连接数量稳步增加,并最终在 30,000 多个端口时开始出现 PySide.QtNetwork.QNetworkReply.NetworkError.UnknownNetworkError已用完;进一步证明 QNetworkReply 没有被正确释放。
PySide 或 PyQt4 也会出现同样的问题。我做错了什么,或者这可能是一个错误?
【问题讨论】:
标签: python pyqt4 pyside qtnetwork