基本上似乎存在大量混淆/模糊性,而不PyEval_InitThreads()应该在什么时候被调用,以及需要哪些API调用.遗憾的是,官方Python文档非常模糊.关于这个主题的stackoverflow已经有很多问题了,事实上,我个人已经问了一个与这个问题几乎完全相同的问题,所以如果这个问题以复制方式结束,我不会特别感到惊讶; 但是考虑到这个问题似乎没有明确的答案.(可悲的是,我没有Guido Van Rossum的快速拨号.)
首先,让我们在这里定义问题的范围:我想做什么? 嗯...我想在C中编写一个Python扩展模块,它将:
pthread在C中使用API的Spawn工作线程好的,让我们从Python文档开始吧.在Python的3.2文档说:
void PyEval_InitThreads()
初始化并获取全局解释器锁.它应该在创建第二个线程或参与任何其他线程操作(如PyEval_ReleaseThread(tstate))之前在主线程中调用.在调用PyEval_SaveThread()或PyEval_RestoreThread()之前不需要它.
所以我的理解是:
PyEval_InitThreads()在生成任何其他线程之前从主线程调用
PyEval_InitThreads锁定GIL所以常识告诉我们,任何创建线程的C扩展模块都必须调用PyEval_InitThreads(),然后释放Global Interpreter Lock.好吧,看起来很简单.所以初步,所有的需要将以下代码:
PyEval_InitThreads(); /* initialize threading and acquire GIL */
PyEval_ReleaseLock(); /* Release GIL */
Run Code Online (Sandbox Code Playgroud)
看起来很简单......但不幸的是,Python 3.2文档也说PyEval_ReleaseLock已经弃用了.相反,我们应该使用PyEval_SaveThread以释放GIL:
PyThreadState*PyEval_SaveThread()
释放全局解释器锁(如果已创建并启用了线程支持)并将线程状态重置为NULL,则返回先前的线程状态(不是NULL).如果已创建锁,则当前线程必须已获取它.
呃......好吧,我想C扩展模块需要说:
PyEval_InitThreads();
PyThreadState* st = PyEval_SaveThread();
Run Code Online (Sandbox Code Playgroud)
实际上,这正是这个stackoverflow回答所说的.除非我在实践中尝试这样做,否则当我导入扩展模块时,Python解释器会立即出现错误.尼斯. …
python python-c-api python-c-extension python-3.x python-3.2