如何在Python中使用C扩展绕过GIL

12 投票
5 回答
6695 浏览
提问于 2025-04-16 02:58

我想在Python中运行一个需要大量CPU资源的程序,并且想知道怎么写C扩展来实现这个。有没有相关的代码示例或者教程可以参考呢?

5 个回答

1

这是一个很好的使用C扩展的例子。你可以搜索的关键词是 Py_BEGIN_ALLOW_THREADS

http://docs.python.org/c-api/init.html#thread-state-and-the-global-interpreter-lock

补充一下,如果你的处理已经是在C语言中进行的,比如图像处理,那么在C扩展中释放锁是个不错的选择。如果你的处理代码主要是在Python中,其他人建议使用 multiprocessing 会更好。通常来说,为了后台处理而重写C代码并不太合理。

7

看看这个 multiprocessing 的文档。一个常常被忽视的事实是,操作系统更喜欢不在全局共享数据,也不把很多线程塞进一个进程里。

如果你还是坚持认为你的程序需要使用线程来处理CPU密集型的任务,可以看看这个关于 在C语言中使用全局解释器锁(GIL)的文档。这会给你很多有用的信息。

9

你可以把一个Python程序拆分成多个进程。操作系统会把这些进程分配到所有的处理器核心上。

你可以这样做。

python part1.py | python part2.py | python part3.py | ... etc.

操作系统会确保这些进程尽可能多地使用资源。你可以通过在 sys.stdinsys.stdout 上使用 cPickle 来轻松地传递信息。

只要稍微动动手,这样做通常能让程序运行得快很多。

当然,对于那些不喜欢的人来说,确实有可能构造出一种算法,让它的速度提升不明显。不过,通常情况下,这种方法能带来很大的好处,而且付出的努力很少。

还有。

为了这个目的进行的结构调整,正好符合为了最大化线程并发而需要的结构调整。所以,先从不共享数据的进程并行开始,直到你能证明共享更多数据会有帮助,然后再转向更复杂的共享所有数据的线程并行。

撰写回答