zoukankan      html  css  js  c++  java
  • 在扩展模块中对python的GIL进行解锁

    在多线程环境下,python虚拟机按照以下方式运行:
       1. 设置GIL(全局解释器锁)
       2. 切换到一个线程中去
       3. 运行
            a. 指定数量的字节码的指令,或者
            b. 线程主动让出控制(可以条用time.sleep(0) )
       4. 把线程设置为睡眠模式
       5. 解锁GIL
       6. 再次重复以上步骤
    调用C/C++扩展函数的时候,GIL会被锁定,直到这个函数结束。由于这期间没有python的字节码被运行,所以线程不会切换

    如果我在扩展模块中调用阻塞式地I/O函数,那么就会发生比较糟糕的事情。

    比如说,我在扩展模块中接受网络数据,如果对端机器没有发送数据,那么我的整个Python程序就会阻塞到这一点,而且不会进行线程的切换。

    如果发生这样的事情,python中的多线程机制就形同虚设了。 

     不过,python允许扩展模块自己对GIL进行解锁,方法如下: 

     解锁GIL的代码结构

    Save the thread state in a local variable. 
    Release the global interpreter lock. 
    ... Do some blocking I/O operation ... 
    Reacquire the global interpreter lock. 
    Restore the thread state from the local variable. 

     由于这个步骤十分通用,Python提供了宏以简化代码,如下:

    Py_BEGIN_ALLOW_THREADS
    ... Do some blocking I/O operation ...
    Py_END_ALLOW_THREADS

    例如,如果我们在代码中使用了 getch 这个函数,那么我们的代码可以这么写:

    # getch test
    Py_BEGIN_ALLOW_THREADS
    int key = getch();
    Py_END_ALLOW_THREADS

    这段代码会被扩展为如下:

     # getch test

    PyThreadState *_save;

    _save = PyEval_SaveThread();
    int key = getch();
    PyEval_RestoreThread(_save);
     
  • 相关阅读:
    专题1
    HDU-6968(DP,和DP)
    ios环境下H5 input 选择图片在函数回调中失效的问题
    vue自定义组件的坑:数组绑定与引号的使用
    关于布局的胡言乱语
    flex布局小结
    微信小程序中overflow:scroll失效的问题
    微信小程序图片的比例问题
    vue用多了反而疏忽了选择器的使用
    在vue项目中做一个类ctrl+f的搜索功能
  • 原文地址:https://www.cnblogs.com/hdtianfu/p/2743799.html
Copyright © 2011-2022 走看看