python 多线程编程之使用进程和全局解释器锁GIL
本文主要介绍如何在python中使用线程。
全局解释器锁:
python代码的执行是由python虚拟机(又名解释器主循环)进行控制的。python中,主循环中同时只能有一个控制线程在执行,就像单核CPU系统中的多线程一样——内存中可以有很多程序,但是在任意给定时刻只有有一个程序在执行。同理,虽然python解释器中可以运行多个线程,但是在任意给定的时刻,只能有一个线程被解释器执行。
上述对python解释器的访问是由全局解释器锁(GIL)控制的。这个锁的核心作用就是用来保证同时只有能一个线程运行。
多线程环境中,python虚拟机将按照一下方式顺序执行:
- 设置GIL
- 切换进一个线程去
- 执行下面操作之一:
- 指定数量的字节码指令
- 线程主动让出控制权(可以调用time.sleep(0)来完成)
- 把线程设置回睡眠模式(切换出线程)
- 解锁GIL
- 重复上述步骤
当调用外部代码(即,任意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的更多相关文章
- python 线程队列、线程池、全局解释器锁GIL
一.线程队列 队列特性:取一个值少一个,只能取一次,没有值的时候会阻塞,队列满了,也会阻塞 queue队列 :使用import queue,用法与进程Queue一样 queue is especial ...
- 并发编程——全局解释器锁GIL
1.全局解释器锁GIL GIL其实就是一把互斥锁(牺牲了效率但是保证了数据的安全). 线程是执行单位,但是不能直接运行,需要先拿到python解释器解释之后才能被cpu执行 同一时刻同一个进程内多个线 ...
- python 什么是全局解释器锁GIL
什么是全局解释器锁GIL Python代码的执行由Python 虚拟机(也叫解释器主循环,CPython版本)来控制,Python 在设计之初就考虑到要在解释器的主循环中,同时只有一个线程在执行,即在 ...
- 21.线程,全局解释器锁(GIL)
import time from threading import Thread from multiprocessing import Process #计数的方式消耗系统资源 def two_hu ...
- 全局解释器锁GIL
我们使用高并发,一次是创建1万个线程去修改一个数并打印结果看现象: from threading import Thread import os def func(args): global n n ...
- 全局解释器锁GIL & 线程锁
1.GIL锁(Global Interpreter Lock) Python代码的执行由Python虚拟机(也叫解释器主循环)来控制.Python在设计之初就考虑到要在主循环中,同时只有一个线程在执行 ...
- Python核心技术与实战——十九|一起看看Python全局解释器锁GIL
我们在前面的几节课里讲了Python的并发编程的特性,也了解了多线程编程.事实上,Python的多线程有一个非常重要的话题——GIL(Global Interpreter Lock).我们今天就来讲一 ...
- Python全局解释器锁 -- GIL
首先强调背景: 1.GIL是什么?GIL的全称是Global Interpreter Lock(全局解释器锁),来源是python设计之初的考虑,为了数据安全所做的决定. 2.每个CPU在同一时间只能 ...
- Python如何规避全局解释器锁(GIL)带来的限制
编程语言分类概念介绍(编译型语言.解释型语言.静态类型语言.动态类型语言概念与区别) https://www.cnblogs.com/zhoug2020/p/5972262.html Python解释 ...
随机推荐
- Netty学习篇⑥--ByteBuf源码分析
什么是ByteBuf? ByteBuf在Netty中充当着非常重要的角色:它是在数据传输中负责装载字节数据的一个容器;其内部结构和数组类似,初始化默认长度为256,默认最大长度为Integer.MAX ...
- Python常见字符串方法函数
1.大小写转换 S.lower() S.upper() 前者将S字符串中所有大写字母转为小写,后者相反 S.title() S.capitalize() 前者返回S字符串中所有单词首字母大写且其他字母 ...
- C#学习笔记03--循环和一维数组
一.循环(重点) 什么时候用循环? 想让一段代码执行多次, 这段代码可能不一样但是一定有一个规律. 1.while 循环 格式: while(循环条件) { 循环执行的代码; } 循环的机制: 当 ...
- linux关闭不必要的用户
#!/bin/bash for user in $( cat /etc/passwd | grep -v root | cut -d ":" -f 1 ) do str=(adm ...
- ES集群操作原理
路由 当你索引一个文档,它被存储在单独一个主分片上.Elasticsearch 是如何知道文档属于哪个分片的呢?当你创建一个新文档,它是如何知道是应该存储在分片 1 还是分片 2 上的呢? 进程不能是 ...
- 转载 C#中DataTable中的Compute方法使用收集
原文: C#中DataTable中的Compute方法使用收集 Compute函数的参数就两个:Expression,和Filter. Expresstion是计算表达式,关于Expression的详 ...
- VMware中windows虚拟机的安装流程
1.打开安装的VMware 15,点击新建虚拟机 2.选择典型即可,点击下一步 3.选择“稍后安装操作系统”,点击下一步 4.选择想安的版本,点击下一步 ...
- fsockopen用feof读取http响应内容的一些问题
在前面三个例子中,都有这么一段代码: while (!feof($fp)) { // 读取文件/数据 //$content .= fgets($fp, 128); //$line = fread($f ...
- 解决mysql java.sql.SQLException: The server time zone value‘XXXXXX' is unrecognized or represents...
解决 java.sql.SQLException: The server time zone value 'XXXXXX' is unrecognized or represents more tha ...
- 数据结构与算法之java语言实现(一):稀疏数组
一.概念&引入 什么是稀疏数组? 稀疏数组是面对一个二维数组中有众多重复元素的情况下,为了节省磁盘空间,将此二维数组转化为更加节省空间的一种数组,我们叫他稀疏数组. 只是听概念或许会看不明白, ...