Python的线程会更简单和更安全,因为它适用于基于I/O的应用程序,所以它们能够绕过GIL。尽管如此,您考虑过使用Twisted或非阻塞socket/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代码仍然获取GIL,现在您必须管理两组逻辑以锁定您的代码。
最终,无论是QT线程还是Python线程都是系统线程的包装器。使用Python线程略微更安全,因为那些没有使用Python编写的部分(隐式使用GIL)在任何情况下都会使用GIL(尽管上述警告仍然适用)。
非阻塞I/O
线程给你的应用程序增加了极大的复杂性。特别是在处理Python解释器与编译模块代码之间已经复杂的交互时。虽然许多人发现基于事件的编程难以理解,但基于事件的非阻塞I/O通常比线程更容易理解。
使用异步I/O,你可以始终确信每个打开的描述符的执行路径是一致和有序的。当然,还有必须解决的问题,例如当依赖于一个打开通道的代码进一步依赖于另一个打开通道返回数据后要调用的代码结果时应该怎么办。
对于基于事件的非阻塞I/O,一个不错的解决方案就是新的Diesel库。目前它只适用于Linux,但它速度非常快且相当优雅。
学习pyevent也是值得时间投资的,它是一个围绕着精妙的libevent库的包装器,为基于事件的编程提供了一个基本框架,并使用系统中最快的可用方法(在编译时确定)。
QCoreApplication.postEvent
,并且已经测试了数千小时。我从未看到过任何问题。只要目标对象位于MainThread或QThread中,我认为这是可以的。我还将其封装在一个很好的库中,参见qtutils。 - three_pineapples