zoukankan      html  css  js  c++  java
  • python 多线程编程之使用进程和全局解释器锁GIL

    本文主要介绍如何在python中使用线程。

    全局解释器锁:

    python代码的执行是由python虚拟机(又名解释器主循环)进行控制的。python中,主循环中同时只能有一个控制线程在执行,就像单核CPU系统中的多线程一样——内存中可以有很多程序,但是在任意给定时刻只有有一个程序在执行。同理,虽然python解释器中可以运行多个线程,但是在任意给定的时刻,只能有一个线程被解释器执行。

    上述对python解释器的访问是由全局解释器锁(GIL)控制的。这个锁的核心作用就是用来保证同时只有能一个线程运行。

    多线程环境中,python虚拟机将按照一下方式顺序执行:

    1. 设置GIL
    2. 切换进一个线程去
    3. 执行下面操作之一:  
      1. 指定数量的字节码指令
      2. 线程主动让出控制权(可以调用time.sleep(0)来完成)
    4. 把线程设置回睡眠模式(切换出线程)
    5. 解锁GIL
    6. 重复上述步骤

    当调用外部代码(即,任意C/C++扩展的内置函数)时,GIL会保持锁定,直到函数执行结束,这是因为在此期间没有python字节码计数。

    例如,对于任意面向IO的python例程(指调用了内置的操作系统C代码的那种),GIL会在IO调用前被释放,以允许其他线程在IO执行的时候运行。而对于那些没有太多的IO操作的代码来说,更倾向于在该线程整个整个时间片内始终占有处理器和GIL。换句话说,IO密集型的python程序要比计算密集型的代码更好的利用多线程机制。

    退出线程

    当一个线程完成函数的执行时,就会退出。另外,我们也可以通过调用类似thread.exit()的方法,或者是类似sys.exit()的方法直接退出进程,还可以通过抛出SystemExit的异常来迫使线程退出。你并不能直接‘终止’一个线程。

    python 中关于线程提供了多个相关的模块,thread(后改为_thread)、threading和Queue等。_thread提供了基本的线程和锁定支持,threading提供了更高级别、功能更全面的线程管理,可以说后者是对对前者进行了封装后的高级体现,一般建议使用后者。使用Queue模块,可以创建一个队列数据,用于在多线程之间进行共享。

    可以通过尝试导入threading模块的方式,确认解释器是否支持线程(如果导入成功,则说明解释器支持线程)。

    首先通过一个不使用线程例子来演示线程是如何工作的。这里要借用time.sleep()函数,以指定的秒数进行‘睡眠’(即程序会暂时停止指定的时间):

    #!/usr/bin/env/ python
    from time import sleep,ctime
    def loop0():
        print('开始循环0次在:',ctime())
        sleep(4)
        print('结束循环0次在:',ctime())
    
    def loop1():
        print('开始循环1次在:',ctime())
        sleep(2)
        print('结束循环1次在:',ctime())
        
    def main():
        print('开始于:',ctime())
        loop0()
        loop1()
        print('所有的任务都完成于:',ctime())
        
    if __name__ == '__main__':
        main()

    下面是执行结果:

    PS C:UsersWC> python E:Python3.6.3workspaceonethr.py
    开始于: Mon Mar 26 21:13:29 2018
    开始循环0次在: Mon Mar 26 21:13:29 2018
    结束循环0次在: Mon Mar 26 21:13:33 2018
    开始循环1次在: Mon Mar 26 21:13:33 2018
    结束循环1次在: Mon Mar 26 21:13:35 2018
    所有的任务都完成于: Mon Mar 26 21:13:35 2018

    该脚本在一个单线程中连续执行两个循环,一个循环必须是在另一个开始前结束,总共的消耗时间是每个循环所用时间之和。

    接下来的章节我们分别具体介绍thread、threading和Queue模块。

  • 相关阅读:
    input、textarea 输入框IOS键盘顶起页面不反弹,Android手机隐藏掉input/textarea
    js调微信支付、支付宝支付
    axios封装
    h5 rem js
    h5 input输入框弹 键盘弹起再关掉,页面被顶起
    webpack vue-loader was used without the corresponding plugin. Make sure to include VueLoaderPlugin
    将url的查询参数解析成字典对象
    设计模式之桥接模式(Bridge)
    Google OKR 目标管理体系学习
    用EF6更新数据库时出现外键错误解决方式
  • 原文地址:https://www.cnblogs.com/hiwuchong/p/8654048.html
Copyright © 2011-2022 走看看