如何在Python中使用C扩展绕过GIL
我想在Python中运行一个需要大量CPU资源的程序,并且想知道怎么写C扩展来实现这个。有没有相关的代码示例或者教程可以参考呢?
5 个回答
这是一个很好的使用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代码并不太合理。
看看这个 multiprocessing 的文档。一个常常被忽视的事实是,操作系统更喜欢不在全局共享数据,也不把很多线程塞进一个进程里。
如果你还是坚持认为你的程序需要使用线程来处理CPU密集型的任务,可以看看这个关于 在C语言中使用全局解释器锁(GIL)的文档。这会给你很多有用的信息。
你可以把一个Python程序拆分成多个进程。操作系统会把这些进程分配到所有的处理器核心上。
你可以这样做。
python part1.py | python part2.py | python part3.py | ... etc.
操作系统会确保这些进程尽可能多地使用资源。你可以通过在 sys.stdin
和 sys.stdout
上使用 cPickle
来轻松地传递信息。
只要稍微动动手,这样做通常能让程序运行得快很多。
当然,对于那些不喜欢的人来说,确实有可能构造出一种算法,让它的速度提升不明显。不过,通常情况下,这种方法能带来很大的好处,而且付出的努力很少。
还有。
为了这个目的进行的结构调整,正好符合为了最大化线程并发而需要的结构调整。所以,先从不共享数据的进程并行开始,直到你能证明共享更多数据会有帮助,然后再转向更复杂的共享所有数据的线程并行。