============================== 15.8 Cå’ŒPythonä¸çš„线程混用 ============================== ---------- 问题 ---------- ä½ æœ‰ä¸€ä¸ªç¨‹åºéœ€è¦æ··åˆä½¿ç”¨Cã€Python和线程, 有些线程是在Cä¸åˆ›å»ºçš„,超出了Python解释器的控制范围。 并且一些线程还使用了Python C APIä¸çš„函数。 ---------- 解决方案 ---------- å¦‚æžœä½ æƒ³å°†Cã€Python和线程混åˆåœ¨ä¸€èµ·ï¼Œä½ 需è¦ç¡®ä¿æ£ç¡®çš„åˆå§‹åŒ–和管ç†Python的全局解释器é”(GIL)。 è¦æƒ³è¿™æ ·åšï¼Œå¯ä»¥å°†ä¸‹åˆ—代ç æ”¾åˆ°ä½ çš„C代ç ä¸å¹¶ç¡®ä¿å®ƒåœ¨ä»»ä½•çº¿ç¨‹è¢«åˆ›å»ºä¹‹å‰è¢«è°ƒç”¨ã€‚ :: #include <Python.h> ... if (!PyEval_ThreadsInitialized()) { PyEval_InitThreads(); } ... 对于任何调用Python对象或Python C APIçš„C代ç ,确ä¿ä½ 首先已ç»æ£ç¡®åœ°èŽ·å–和释放了GIL。 è¿™å¯ä»¥ç”¨ ``PyGILState_Ensure()`` å’Œ ``PyGILState_Release()`` æ¥åšåˆ°ï¼Œå¦‚下所示: :: ... /* Make sure we own the GIL */ PyGILState_STATE state = PyGILState_Ensure(); /* Use functions in the interpreter */ ... /* Restore previous GIL state and return */ PyGILState_Release(state); ... æ¯æ¬¡è°ƒç”¨ ``PyGILState_Ensure()`` 都è¦ç›¸åº”的调用 ``PyGILState_Release()`` . ---------- 讨论 ---------- 在涉åŠåˆ°Cå’ŒPython的高级程åºä¸ï¼Œå¾ˆå¤šäº‹æƒ…一起åšæ˜¯å¾ˆå¸¸è§çš„—— å¯èƒ½æ˜¯å¯¹Cã€Pythonã€C线程ã€Python线程的混åˆä½¿ç”¨ã€‚ åªè¦ä½ ç¡®ä¿è§£é‡Šå™¨è¢«æ£ç¡®çš„åˆå§‹åŒ–,并且涉åŠåˆ°è§£é‡Šå™¨çš„C代ç 执行了æ£ç¡®çš„GIL管ç†ï¼Œåº”该没什么问题。 è¦æ³¨æ„的是调用 ``PyGILState_Ensure()`` 并ä¸ä¼šç«‹åˆ»æŠ¢å 或ä¸æ–解释器。 如果有其他代ç æ£åœ¨æ‰§è¡Œï¼Œè¿™ä¸ªå‡½æ•°è¢«ä¸æ–知é“那个执行代ç 释放掉GIL。 在内部,解释器会执行周期性的线程切æ¢ï¼Œå› æ¤å¦‚果其他线程在执行, 调用者最终还是å¯ä»¥è¿è¡Œçš„(尽管å¯èƒ½è¦å…ˆç‰ä¸€ä¼šï¼‰ã€‚