本文主要介绍如何在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:\Users\WC> python E:\Python3.6.3\workspace\onethr.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模块。

python 多线程编程之使用进程和全局解释器锁GIL的更多相关文章

  1. python 线程队列、线程池、全局解释器锁GIL

    一.线程队列 队列特性:取一个值少一个,只能取一次,没有值的时候会阻塞,队列满了,也会阻塞 queue队列 :使用import queue,用法与进程Queue一样 queue is especial ...

  2. 并发编程——全局解释器锁GIL

    1.全局解释器锁GIL GIL其实就是一把互斥锁(牺牲了效率但是保证了数据的安全). 线程是执行单位,但是不能直接运行,需要先拿到python解释器解释之后才能被cpu执行 同一时刻同一个进程内多个线 ...

  3. python 什么是全局解释器锁GIL

    什么是全局解释器锁GIL Python代码的执行由Python 虚拟机(也叫解释器主循环,CPython版本)来控制,Python 在设计之初就考虑到要在解释器的主循环中,同时只有一个线程在执行,即在 ...

  4. 21.线程,全局解释器锁(GIL)

    import time from threading import Thread from multiprocessing import Process #计数的方式消耗系统资源 def two_hu ...

  5. 全局解释器锁GIL

    我们使用高并发,一次是创建1万个线程去修改一个数并打印结果看现象: from threading import Thread import os def func(args): global n n ...

  6. 全局解释器锁GIL & 线程锁

    1.GIL锁(Global Interpreter Lock) Python代码的执行由Python虚拟机(也叫解释器主循环)来控制.Python在设计之初就考虑到要在主循环中,同时只有一个线程在执行 ...

  7. Python核心技术与实战——十九|一起看看Python全局解释器锁GIL

    我们在前面的几节课里讲了Python的并发编程的特性,也了解了多线程编程.事实上,Python的多线程有一个非常重要的话题——GIL(Global Interpreter Lock).我们今天就来讲一 ...

  8. Python全局解释器锁 -- GIL

    首先强调背景: 1.GIL是什么?GIL的全称是Global Interpreter Lock(全局解释器锁),来源是python设计之初的考虑,为了数据安全所做的决定. 2.每个CPU在同一时间只能 ...

  9. Python如何规避全局解释器锁(GIL)带来的限制

    编程语言分类概念介绍(编译型语言.解释型语言.静态类型语言.动态类型语言概念与区别) https://www.cnblogs.com/zhoug2020/p/5972262.html Python解释 ...

随机推荐

  1. Java流程控制之(三)嵌套

    目录 嵌套循环 for循环嵌套 while循环嵌套 总结 之前谈到各种循环结构,有for循环啊,有while循环啊,可以完成不断重复的动作,相当方便.那么如果好多个循环结合再一次,又是如何实现效果的呢 ...

  2. js 根据指定的多个索引,删除相应的数组元素。splice + sort

    更新于2018-04-19 var productItems = ["a", "b", "c", "d"]; var i ...

  3. 使用zuul实现验证自定义请求头中的token

    路由:她会把外部所有对请求转发到具体的微服务实例上,是实现外部访问同一接口的基础 过滤: 就是权限的检查, 判断当前的请求是否有权限区访问那些服务集群 搭建后台网关: 导入eureka - clien ...

  4. Golang 指针理解

    目录 0x00 指针地址和指针类型 0x01 从指针获取指针指向的值 0x02 使用指针修改值 0x03 返回函数中局部变量 0x04 使用 new() 创建指针 0x05 flag包的指针技术 0x ...

  5. JRE JDK JVM的区别

    jdk>jre>jvm jdk是面向开发者具有编译功能: jre是面向用户的,主要是class文件的运行,假如我们只有编译好的class文件和jre,那么就可以运行class了. jvm是 ...

  6. 从面试官甄别项目经验的角度,说说如何在简历中写项目经验(java后端方向)

    在大多的JD(职位介绍)里,会写明该职位需要xx时间的相关经验,换句话说就是需要在简历中看到一定年限的相关商业项目经验,否则估计连面试的机会都没. 在本文里,不讨论这种门槛是否合理,而会以Java相关 ...

  7. 2019年12月4日Linux开发手记

    OK,经过昨天对V4L2工作流程的学习,现在已经大体了解了V4L2的工作原理,现在开始对V4L2的API的学习,目标:1.打开摄像头 2.储存图像 3.关闭摄像头,API网址:Linux Media ...

  8. Server MyEclipse Tomcat v7.0 was unable to start within 45 seconds. If the server requires more time

    启动Tomcat服务器时经常遇到这个错误, Server MyEclipse Tomcat v7.0 was unable to start within 45 seconds. If the ser ...

  9. Java语法进阶13-文件、IO流

    File File是文件和目录路径名的抽象表示形式,即File类是文件或目录的路径,而不是文件本身,因此File类不能直接访问文件内容本身,如果需要访问文件内容本身,则需要使用输入/输出流. File ...

  10. mysql的两阶段协议(封锁定理,虫洞事务)

    我们都知道数据库的事务具有ACID的四个属性:原子性,一致性,隔离性和持久性.然后在多线程操作的情况下,如果不能保证事务的隔离性,就会造成数据的修改丢失(事务2覆盖了事务1的修改结果).读到脏数据(事 ...