首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python: GIL上下文切换

Python: GIL上下文切换
EN

Stack Overflow用户
提问于 2013-04-27 22:40:40
回答 2查看 1.9K关注 0票数 9

因此,我通常非常了解Python中的Global Interpreter Lock (GIL)是如何工作的。本质上,当解释器运行时,一个线程为N个刻度保存GIL (其中N可以使用sys.setcheckinterval设置),此时GIL被释放,另一个线程可以获取GIL。如果一个线程开始I/O操作,也会发生这种情况。

我有点困惑的是,这一切是如何与C扩展模块一起工作的。

如果您有一个获得GIL的C扩展模块,然后使用PyEval_EvalCode执行一些python代码,那么解释器可以释放GIL并将其交给其他线程吗?还是获得GIL的C线程将永久保存GIL,直到PyEval_EvalCode返回并在C中显式释放GIL?

代码语言:javascript
复制
PyGILState gstate = PyGILState_Ensure();

....

/* Can calling PyEval_EvalCode release the GIL and let another thread acquire it?? */
PyObject* obj = PyEval_EvalCode(code, global_dict, local_dict); 

PyGILState_Release(gstate);
EN

回答 2

Stack Overflow用户

发布于 2013-04-28 12:03:43

是的,解释器总是可以释放GIL;在解释了足够多的指令之后,它会将其释放给其他线程,或者如果它执行了一些I/O操作,就会自动释放它。注意,自从最近的Python3.x以来,这个标准不再基于已执行的指令的数量,而是取决于是否已经过了足够的时间。

要获得不同的效果,您需要一种以“原子”模式获取GIL的方法,方法是在显式释放GIL之前不要释放它。到目前为止,这是不可能的(但请参阅https://bitbucket.org/arigo/cpython-withatomic的实验版本)。

票数 4
EN

Stack Overflow用户

发布于 2013-10-15 15:41:19

正如Armin所说,GIL可以在PyEval_EvalCode内部释放。当它回来的时候,它当然又被收购了。

最好的方法就是确保您的代码能够处理这个问题。例如,在释放GIL之前,在有C指针的任何对象上递增。此外,如果可能出现Python代码再次调用相同函数的情况,请小心。如果你有另一个互斥,你可以很容易地结束在一个死锁。使用递归安全互斥,在等待它们时,您应该释放GIL,这样原始线程就可以释放这样的互斥对象。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16257587

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档