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);
     
  • 相关阅读:
    C#模拟POST表单提交 WebClient
    视频广告屏蔽器(附下载地址)
    SQL Server 不同数据库导入指定数据解决方案
    WinRAR(WinZip)压缩与解压实现(C#版Window平台)
    Visual Studio 扩展包(.vsix)制作
    ORM for Net主流框架汇总与效率测试
    文件删除小助手
    C# 控制台应用程序输出颜色字体[更正版]
    IE与IE内核浏览器的那点事
    where in的sql语句按照指定ID进行排序的解决方法
  • 原文地址:https://www.cnblogs.com/hdtianfu/p/2743799.html
Copyright © 2011-2022 走看看