[Python 多线程] GIL全局解释器锁 (十三)
Queue
标准库queue模块,提供FIFO(先进先出)的Queue、LIFO(后进先出)的队列、优先队列。
Queue类是线程安全的,适用于多线程间安全的交换数据。内部使用了Lock和Condition。
使用魔术方法,实现的容器的大小,是不准确的。not reliable!
因为在多线程中,如果不加锁,是不可能获得准确的大小的,因为当刚刚读取到一个大小数值,还没有取走,就有可能被其它线程修改了。
Queue类的size虽然加了锁,但是,依然不能保证立即get、put就能成功,因为读取队列大小qsize和get、put方法是分开的。
全局解释器锁:
CPython在解释器级别的一把锁,叫GIL全局解释器锁。(Ruby也有)
Global Interpreter Lock
程序编译成字节码,程序想跑多线程,但是GIL保证CPython进程中,同一时刻只能有一个线程执行字节码。
所以,哪怕是在多CPU的情况下,即使每个线程恰好调度到了每个CPU上,有了这把大锁,同时只能有一个CPU使用CPython执行一个线程的字节码,其它线程只能阻塞等待。
也就是说只要有这把锁,CPython中根本就没有真正的多线程。同一时刻只有CPU的一个线程被调度使用。
GIL锁从CPython最初版本到现在一直存在。
CPython中:
IO密集型,由于线程阻塞,就会调度其它线程;(wait会让出时间片,让其它线程有机会被调度、sleep不会),大量使用网络IO、磁盘IO
CPU密集型,当前线程可能会连续的获得GIL,导致其它线程几乎无法使用CPU。(刚释放锁就又夺走了),大量占用CPU计算得数
IO密集型,使用多线程;CPU密集型,使用多进程,绕开GIL。
多进程时,同样每个进程内的线程也受GIL这把大锁的限制。
新版CPython正在努力优化GIL的问题,但不是移除。
如果非要使用多线程的效率问题,请绕行,选择其它语言erlang、Go等。
保留GIL的原因:
独裁者Guido坚持简单哲学(import this),对于初学者门槛低,不需要高深的系统只是也能安全、简单的使用Python。
而且移除GIL,会降低CPython单线程的执行效率。
模拟CPU密集型:
#模拟CPU密集型
import threading,logging,time,random,datetime
DATEFMT="%H:%M:%S"
FORMAT = "[%(asctime)s]\t [%(threadName)s,%(thread)d] %(message)s"
logging.basicConfig(level=logging.INFO,format=FORMAT,datefmt=DATEFMT) def calc():
sum = 0
for _ in range(100000000):
sum += 1 start =datetime.datetime.now() calc()
calc()
calc()
calc()
calc() delta = (datetime.datetime.now() -start).tota 运行结果:
38.820701
上例是单线程串行执行结果。
对上例使用多线程:
#模拟CPU密集型 多线程
import threading,logging,time,random,datetime
DATEFMT="%H:%M:%S"
FORMAT = "[%(asctime)s]\t [%(threadName)s,%(thread)d] %(message)s"
logging.basicConfig(level=logging.INFO,format=FORMAT,datefmt=DATEFMT) def calc():
sum = 0
for _ in range(100000000):
sum += 1 start =datetime.datetime.now() lst = [] for _ in range(5):
t = threading.Thread(target=calc)
t.start()
lst.append(t) for t in lst:
t.join() delta = (datetime.datetime.now() -start).total_seconds()
print(delta) 运行结果:
38.782773
上面分别使用了单线程和多线程来测试效率,耗时都在38秒左右,所以因为GIL的存在,CPython中多线程根本没有任何优势,和单线程执行效率相当。
[Python 多线程] GIL全局解释器锁 (十三)的更多相关文章
- 网络编程之多线程——GIL全局解释器锁
网络编程之多线程--GIL全局解释器锁 一.引子 定义: In CPython, the global interpreter lock, or GIL, is a mutex that preven ...
- python 并发编程 多线程 GIL全局解释器锁基本概念
首先需要明确的一点是GIL并不是Python的特性,它是在实现Python解析器(CPython)时所引入的一个概念. 就好比C++是一套语言(语法)标准,但是可以用不同的编译器来编译成可执行代码. ...
- Python 36 GIL全局解释器锁 、vs自定义互斥锁
一:GIL全局解释器锁介绍 在CPython中,全局解释器锁(或GIL)是一个互斥锁, 它阻止多个本机线程同时执行Python字节码.译文:之所以需要这个锁, 主要是因为CPython的内存管理不是线 ...
- python基础--GIL全局解释器锁、Event事件、信号量、死锁、递归锁
ps:python解释器有很多种,最常见的就是C python解释器 GIL全局解释器锁: GIL本质上是一把互斥锁:将并发变成串行,牺牲效率保证了数据的安全 用来阻止同一个进程下的多个线程的同时执行 ...
- 关于python的GIL全局解释器锁的简单理解
GIL是解释器内部的一把锁,确切一点说是CPython解释器内部的一把锁,所以要注意区分 这和我们在Python代码中使用线程锁Lock并不是一个层面的概念. 1. GIL产生的背景: 在CPytho ...
- Python 之 GIL 全局解释器锁
GIL(全局解释器锁) GIL锁即全局解释器锁,是 CPython 解释器的特性.它的作用是保证了同一时刻只有一个线程执行 Python 字节码. 它并不是 Python 的特性,它的存在是 CPyt ...
- python GIL全局解释器锁与互斥锁 目录
python 并发编程 多线程 GIL全局解释器锁基本概念 python 并发编程 多线程 GIL与Lock python 并发编程 多线程 GIL与多线程
- python GIL全局解释器锁,多线程多进程效率比较,进程池,协程,TCP服务端实现协程
GIL全局解释器锁 ''' python解释器: - Cpython C语言 - Jpython java ... 1.GIL: 全局解释器锁 - 翻译: 在同一个进程下开启的多线程,同一时刻只能有一 ...
- python并发编程-多线程实现服务端并发-GIL全局解释器锁-验证python多线程是否有用-死锁-递归锁-信号量-Event事件-线程结合队列-03
目录 结合多线程实现服务端并发(不用socketserver模块) 服务端代码 客户端代码 CIL全局解释器锁****** 可能被问到的两个判断 与普通互斥锁的区别 验证python的多线程是否有用需 ...
随机推荐
- 01 使用Git基本方法
什么是Git? Git是目前世界上最先进的分布式版本控制系统(没有之一). 你得先有一个Git仓库,才能进行操作.创库就是Git存放你要保存的快照的数据的地方. 拥有一个Git仓库,有两种方法. 创建 ...
- 二进制之Java中的进制(二)
1. jdk中的进制转换 十进制转十六进制 Integer.toHexString(int i); 十进制转八进制 Integer.toOctalString(int i); 十进制转二进制 Inte ...
- The configuration section 'system.serviceModel' cannot be read because it is missing a section decla
将Asp.Net 2.0的Web Site搭建在IIS7(7.5)上时,运行出现500.19错误, 错误提示为 The configuration section 'system.serviceMod ...
- bash shell学习笔记(一)—— 常用命令
一.基本的bash shell命令 1.默认bash shell 提示符是美元符号($); 2.bash手册 使用man命令来访问存储在Linux系统上的手册页面,如: bogon:~ Mac$ ma ...
- 《JavaWeb从入门到改行》fileupload,没毛病
目录: » fileupload API > 文件上传的要求 > fileupload组件 » 上传细节的代码演示 » 项目案例-上传头像并显示 fileupload API 文 ...
- Runtime 打开记事本
package com.direct.str; import java.io.IOException; public class RunTimeDemo { /** * @param args */ ...
- cf1088D. Ehab and another another xor problem(思维)
题意 题目链接 系统中有两个数\((a, b)\),请使用\(62\)以内次询问来确定出\((a, b)\) 每次可以询问两个数\((c, d)\) 若\(a \oplus c > b \opl ...
- Python之面向对象继承复习
总结:self是谁就从谁开始寻找
- attr()与prop()之全选、反选问题
获取js dom原生属性的时候最好用prop()方法,获取自己添加的属性时用attr() 原文:http://blog.sina.com.cn/s/blog_bf5ce8cc0102vuyt.html ...
- ubuntu 14.04/14.10 iptables 防火墙设置
1. 一键批处理设置 [plain] view plaincopyprint? #!/bin/bash PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/loc ...