多线程Python的C扩展能否提高性能?

多线程Python的C扩展能否提高性能?,python,multithreading,gil,Python,Multithreading,Gil,我听说过Python的GIL问题,即在多核机器中一次只能有一个Python线程执行Python字节码。因此,多线程Python程序不是一个好主意 我想知道是否可以编写一个C扩展,它使用pthread来潜在地提高程序的性能。我想在我的C扩展中创建一个线程,并使其与Python的主线程并行运行 我的假设是,Python主线程将执行与IO更相关的操作,而C扩展中的pthread将花费大部分时间进行计算。Python主线程使用队列(类似于生产者-消费者模型)与C扩展中的线程通信 使用Python的多线程

我听说过Python的GIL问题,即在多核机器中一次只能有一个Python线程执行Python字节码。因此,多线程Python程序不是一个好主意

我想知道是否可以编写一个C扩展,它使用
pthread
来潜在地提高程序的性能。我想在我的C扩展中创建一个线程,并使其与Python的主线程并行运行

我的假设是,Python主线程将执行与IO更相关的操作,而C扩展中的
pthread
将花费大部分时间进行计算。Python主线程使用队列(类似于生产者-消费者模型)与C扩展中的线程通信


使用Python的多线程与C扩展之间有什么区别吗?

Python解释器不知道C以任何方式启动的线程,因此它们可以愉快地搅动自己的CPU时间


但是,我怀疑这是解决性能问题的正确方法。首先尝试使用多进程和多进程模块。如果进程间IO过多,则可能会导致像C线程一样的欺骗。这将使您的程序更复杂一个数量级,因此尽可能避免它。

要回答您最初的问题:


是的,C扩展可以不受GIL的影响,只要它们在没有GIL的情况下不调用任何Python API函数。因此,如果需要与Python应用程序通信,则需要获得GIL。如果您不想让C API太脏,可以使用
ctypes
调用C库(它可以像往常一样使用
pthreads
),或者使用Cython以类似Python的语法编写C扩展。

如果一个线程运行CPU绑定,而另一个线程运行IO绑定,我看不出有问题

IO绑定线程将调用IO例程,这些例程通常在执行任务时释放GIL,从而有效地允许另一个线程运行


因此,只有当“简单”解决方案确实不能按您希望的方式工作时,才尝试切换它。

我对多线程编程一无所知,但确实会改变您的想法?@PaulD.Waite我刚刚玩了多处理模块,我认为它可以避免GIL问题。我将试着看看情况如何。在美国,“GIL问题”不再像以前那样是一个重大问题。在考虑诸如线程化C扩展之类的复杂解决方案之前,请确认GIL实际上是您案例中的瓶颈,因为它会损害代码的可读性和可维护性。我怀疑像这里的其他人所建议的那样,标准库多处理模块就足够了。“如果他们在没有GIL的情况下不调用任何Python API函数”你的意思是c扩展不调用任何持有GIL的Python API,因此它可以在没有GIL的情况下运行,对吗?调用任何pythonapi函数都需要持有GIL(它是一个锁),这迫使Python程序一次只运行一个线程。如果释放锁,则无法调用Python API函数,但可以自由运行任意多个并发线程。感谢您的澄清,我猜您的意思是,ctypes已经在内部处理了GIL的获取和释放。
ctypes
可以调用C函数,而C函数将在没有GIL的情况下运行。如果C函数调用
ctypes
提供的回调函数(Python函数),那么在调用函数之前将重新获取GIL。因此,您实际上可以生成一个线程,使用Python函数作为回调调用
ctypes
,并在事情完成时通过回调得到通知。