time.sleep(secs) 可以暂停 QNetworkAccessManager 是不是异步请求?
Posted
技术标签:
【中文标题】time.sleep(secs) 可以暂停 QNetworkAccessManager 是不是异步请求?【英文标题】:can time.sleep(secs) suspend QNetworkAccessManager does request asynchronously?time.sleep(secs) 可以暂停 QNetworkAccessManager 是否异步请求? 【发布时间】:2014-12-21 14:54:59 【问题描述】:QNetworkAccessManager
可以异步执行请求,time.sleep(secs)
可以暂停执行给定的秒数。我被下面的代码弄糊涂了。 t2
这里总是大于10秒吗?
在此处的代码中未使用time.sleep(secs)
,已完成的插槽getWebPageSRC
在固定的时间内被调用,大约为3 秒。
我现在已经测试了几次,发现 t2 总是大于 10 秒。谁能解释一下为什么?
de myMethod(self):
...
reply.finished.connect(self.getWebPageSRC)
self.t=time.clock()
time.sleep(10)
def getWebPageSRC(self):
t2=time.clock()-self.t
print(t2)
附:由于 QNAM 异步执行其工作,我认为它在另一个线程中工作,因此有自己的事件循环,那么 time.sleep(secs) 是否暂停所有线程的所有 Qt 事件循环或只是它所在线程的事件循环?在主线程中休眠是否会暂停所有其他线程的事件循环?
【问题讨论】:
对不起,我让你的问题更适合英语。 ;-) 你使用的是 pyqt 还是 pyside?没有足够的空间来添加两者。 @lpapp 谢谢,为我糟糕的英语感到羞耻......我正在使用 PyQt,“没有足够的空间来添加两者。”我不明白你的意思。跨度> 我们最多可以为问题添加五个标签。 【参考方案1】:这个问题似乎是理论上的,因为它在实践中不应该成为一个问题,因为这闻起来像是可疑的设计或错误的快速解决方法。
话虽如此,原因还是比较简单的:当你开始睡眠时,Qt 事件循环无法完成它的工作,因此在你从阻塞睡眠中醒来之前,事件循环无法从事件队列中处理你的槽。
如果你,比如说,睡在另一个线程中,这不会是一个问题,尽管一开始即使这样也会过于奇怪,但在这里你睡在应该异步处理事件的线程(块)中。
毕竟在 Qt 应用程序中休眠没有多大意义。 Qt 主要用于异步操作,尤其是像 QtNetwork 这样的 QIODevice 接口。
使用Qt时,忘记这个语句的存在:
time.sleep(10)
每当您考虑阻止以等待回复时,您都可以使用同步 API,尽管即使这样也不是完全同步是公平的:
# 10000 msecs = 10 secs
myNetworkReply.waitForBytesWritten(10000)
我可能会走得更远:我可能会避免在 python 应用程序中使用 Qt,而不是严格的 UI。也就是说,其余的一切都可以通过 python 手段来实现,通常从 python 应用程序更好更容易。我认为您应该专注于 GUI,但这肯定是基于意见的。相关的替代方案是 asyncore、twisted 等。
【讨论】:
是的,你是对的。在 QThread 文档中说:wait() 和 sleep() 函数通常是不必要的,因为 Qt 是一个事件驱动的框架。考虑监听finished() 信号,而不是wait()。考虑使用 QTimer,而不是 sleep() 函数。 @iMath:如果问题解决了,请选择一个答案。 我已经补充了问题,还没有收到任何通知? @iMath:请永远不要更改您的问题,并且根据您的要求,您的 QNAM 不会在另一个线程中运行,但即使是这样,睡眠也无法像答案那样阻塞另一个线程. 由于 QNAM 异步工作,我认为它可以在另一个线程中工作,对吗?【参考方案2】:无论 QNAM 以异步方式执行其工作,它仍然在主线程中运行。停止主线程 10 秒也会阻塞 QNAM。
【讨论】:
由于 QNAM 异步工作,我认为它在另一个线程中工作,因此有自己的事件循环,所以 time.sleep(secs) 暂停所有线程的所有 Qt 事件循环或只是它在线程的事件循环中?在主线程中休眠是否会暂停所有其他线程的事件循环? 不,它在另一个线程中不起作用,除非您明确将其放入。 谢谢,time.sleep(secs) 是暂停所有线程的所有 Qt 事件循环,还是暂停它所在线程的事件循环?在主线程中休眠是否会暂停所有其他线程的事件循环?【参考方案3】:QNetworkAccessManager
确实可以异步执行请求,但它们都在应用程序主线程中执行。所以当你打电话时
time.sleep(10)
主线程被阻塞 10 秒,在阻塞期间没有做任何其他事情。那是因为这里的QNetworkAccessManager
不在其他线程中。
【讨论】:
由于 QNAM 异步工作,我认为它在另一个线程中工作,因此有自己的事件循环,所以 time.sleep(secs) 暂停所有线程的所有 Qt 事件循环或只是它在线程的事件循环中?在主线程中休眠是否会暂停所有其他线程的事件循环? @iMath 异步工作并不意味着它有自己的事件循环。许多对象可以使用信号和槽在主事件循环中异步执行。 QNAM 也不存在于其他线程中。所以这里阻塞主事件循环会导致阻塞 QNAM。 谢谢,time.sleep(secs) 是暂停所有线程的所有 Qt 事件循环,还是暂停它所在线程的事件循环?在主线程中休眠是否会暂停所有其他线程的事件循环? @iMathtime.sleep(secs)
只是暂停它的线程的事件循环(这里只是主事件循环)。因此,如果您创建任何其他线程,它们不会受到影响并继续运行。在主线程中休眠只是挂起主线程。以上是关于time.sleep(secs) 可以暂停 QNetworkAccessManager 是不是异步请求?的主要内容,如果未能解决你的问题,请参考以下文章