使用并行崩溃的程序:在没有gil的情况下不允许丢弃拥有的Python对象
我在Cython文档网站上读到,几乎所有python代码都可以在Cython中使用。正如我们所知,这是一个演示Python和GIL局限性的著名片段。我试图在Cython中重新创建一个解决方案 然而,我在编译这段代码时遇到了这个问题使用并行崩溃的程序:在没有gil的情况下不允许丢弃拥有的Python对象,python,c,python-3.x,types,cython,Python,C,Python 3.x,Types,Cython,我在Cython文档网站上读到,几乎所有python代码都可以在Cython中使用。正如我们所知,这是一个演示Python和GIL局限性的著名片段。我试图在Cython中重新创建一个解决方案 然而,我在编译这段代码时遇到了这个问题 %%cython from threading import Thread import time def countdown(n): while n > 0: n -= 1 COUNT = 10000000 start =
%%cython
from threading import Thread
import time
def countdown(n):
while n > 0:
n -= 1
COUNT = 10000000
start = time.time()
t1 = Thread(target=countdown,args=(COUNT/2,))
t2 = Thread(target=countdown,args=(COUNT/2,))
with nogil:
t1.start();t2.start()
t1.join();t2.join()
end = time.time()
print(end-start)
从我的代码中可以明显看出,我对Cython是相当陌生的。我想就如何修复它提出一些建议。这行不通 线程库返回Python对象。要与他们互动,你需要GIL。因此,在没有GIL的情况下,您不能期望调用
.start()
或.join()
更有用的是用nogil块包装函数中不需要GIL的部分。例如,countdown
中的循环可以很容易地在没有GIL的情况下完成(实际上,C编译器很可能会发现这个循环完全没有意义,并将其完全删除,但这是一个单独的问题)
这允许在没有GIL的情况下完成大部分工作,但需要在功能开始和结束时保持GIL
还有第二个复杂问题:常规Python代码偶尔会释放GIL,以便在需要时允许其他线程运行。Cython通常不会这样做(尽管它可能会调用Python代码,所以您不能依赖它)。因此,在Cython中编写
倒计时
可能是有意义的,但不是启动线程的代码
我怀疑这不会是一个问题,但最好是安全。Hi@DavidW。感谢您提供此解决方案。我这样做是因为我希望能够传递
nogil
指令中的函数。可以使用哪些其他方法传入这些函数?简而言之:我想创建一个通用的并行处理模板,在其中我可以传递自定义函数。这在Cython是可以实现的吗?我不知道有什么办法,我也不明白你为什么要这么做。
Error compiling Cython file:
------------------------------------------------------------
...
start = time.time()
t1 = Thread(target=countdown,args=(COUNT/2,))
t2 = Thread(target=countdown,args=(COUNT/2,))
with nogil:
t1.start();t2.start()
^
------------------------------------------------------------
/Users/sanskar/.ipython/cython/_cython_magic_bb84bd2392afb02224d35c81782c007c.pyx:14:12: Discarding owned Python object not allowed without gil
Error compiling Cython file:
------------------------------------------------------------
...
def countdown(int n):
with nogil:
while n > 0:
n -= 1