为了账号安全,请及时绑定邮箱和手机立即绑定

PyQt应用程序中的线程:使用Qt线程还是Python线程?

PyQt应用程序中的线程:使用Qt线程还是Python线程?

隔江千里 2019-07-22 18:46:48
PyQt应用程序中的线程:使用Qt线程还是Python线程?我正在编写一个GUI应用程序,它通过Web连接定期检索数据。由于这个检索需要一段时间,这会导致UI在检索过程中没有响应(不能分割成更小的部分)。这就是为什么我想把网络连接外包给一个单独的工作线程。是的,我知道,现在我有了两个问题.]无论如何,应用程序使用PyQt 4,所以我想知道更好的选择是:使用QT的线程还是使用Pythonthreading模块?每种方法的优点/缺点是什么?还是你有完全不同的建议?编辑(再赏金):而在我的特殊情况下,解决方案可能是使用非阻塞网络请求,如杰夫·奥伯和LukášLalinsk建议(基本上将并发问题留给网络实现),我仍然希望对一般问题有一个更深入的答案:与本机Python线程相比,使用PyQt 4(即Qt)线程有哪些优点和缺点?threading模块)?编辑2:谢谢你的回答。虽然没有100%的一致意见,但似乎普遍认为答案是“使用Qt”,因为这样做的好处是与库的其他部分集成,同时没有造成真正的缺点。对于任何希望在这两个线程实现之间进行选择的人,我强烈建议他们阅读这里提供的所有答案,包括Pyqt邮件列表线程方丈链接到。对于奖金,我考虑了几个答案;最后,我选择了方丈作为非常相关的外部参考;然而,这是一个亲密的选择。再次感谢。
查看完整描述

3 回答

?
繁华开满天机

TA贡献1816条经验 获得超4个赞

优势QThread它与Qt库的其他部分集成在一起。也就是说,qt中的线程感知方法需要知道它们在哪个线程中运行,并且要在线程之间移动对象,您需要使用QThread..另一个有用的特性是在线程中运行您自己的事件循环。

如果您正在访问HTTP服务器,则应考虑QNetworkAccessManager.


查看完整回答
反对 回复 2019-07-22
?
慕仙森

TA贡献1827条经验 获得超7个赞

这是讨论不久前在PyQt邮件列表中。引用乔瓦尼·巴霍的话评论意见关于这个问题:

基本上是一样的。主要区别在于QThread与Qt(异步信号/时隙、事件循环等)更好地集成在一起。另外,您不能使用Python线程中的Qt(例如,不能通过QApplication.postEvent将事件发送到主线程):为此需要一个QThread。

如果要以某种方式与Qt交互,则一般经验法则可能是使用QThread,否则使用Python线程。

之前,PyQt的作者对此发表了一些评论:“它们都是围绕同一个本机线程实现的包装器”。两种实现都以相同的方式使用GIL。


查看完整回答
反对 回复 2019-07-22
?
HUH函数

TA贡献1836条经验 获得超4个赞

Python的线程将更简单、更安全,而且由于它适用于基于I/O的应用程序,所以它们能够绕过GIL。也就是说,您是否考虑过使用Twisted或非阻塞套接字/SELECT进行非阻塞I/O?

编辑:关于线程的更多信息

Python线程

Python的线程是系统线程。然而,Python使用全局解释器锁(GIL)来确保解释器一次只执行一定大小的字节码指令块。幸运的是,Python在输入/输出操作期间释放了GIL,使得线程对于模拟非阻塞I/O非常有用。

重要警告:这可能会产生误导,因为字节码指令的数量确实有误导性。对应程序中的行数。在Python中,即使是单个赋值也不一定是原子的,因此必须使用互斥锁。任何必须以原子方式执行的代码块,即使使用GIL。

QT线程

当Python将控制交给第三方编译模块时,它会释放GIL。模块的责任是在需要时确保原子性。当控制权被传回时,Python将使用GIL。这可能会使用第三方库与线程混淆。使用外部线程库更加困难,因为它增加了控制在模块手中的位置和时间与解释器之间的不确定性。

Qt线程使用释放的GIL操作。Qt线程能够同时执行Qt库代码(以及其他不获取GIL的编译模块代码)。但是,在Qt线程上下文中执行的Python代码仍然获得了吉尔,现在你必须管理用于锁定代码的一组逻辑。

最后,Qt线程和Python线程都是系统线程的包装器。Python线程使用起来稍微安全一些,因为那些没有用Python编写的部分(隐式地使用GIL)在任何情况下都使用GIL(尽管上面的警告仍然适用)。

无阻塞I/O

线程给应用程序增加了极大的复杂性。特别是在处理Python解释器和编译的模块代码之间已经很复杂的交互时。虽然许多人发现基于事件的编程很难遵循,但是基于事件的、非阻塞的I/O通常比线程更难推理。

使用异步I/O,您可以始终确保,对于每个打开的描述符,执行的路径是一致和有序的。显然,必须解决一些问题,例如当依赖于一个开放通道的代码进一步取决于另一个公开通道返回数据时调用的代码的结果时,该怎么办。

基于事件的非阻塞I/O的一个很好的解决方案是新的。柴油图书馆。目前它仅限于Linux,但速度非常快,而且相当优雅。

这也是值得你花时间去学习的。化脓性的包装器,它为基于事件的编程提供了一个基本框架,使用系统可用的最快方法(在编译时确定)。


查看完整回答
反对 回复 2019-07-22
  • 3 回答
  • 0 关注
  • 2024 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信