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全局解释器锁 (十三)的更多相关文章

  1. 网络编程之多线程——GIL全局解释器锁

    网络编程之多线程--GIL全局解释器锁 一.引子 定义: In CPython, the global interpreter lock, or GIL, is a mutex that preven ...

  2. python 并发编程 多线程 GIL全局解释器锁基本概念

    首先需要明确的一点是GIL并不是Python的特性,它是在实现Python解析器(CPython)时所引入的一个概念. 就好比C++是一套语言(语法)标准,但是可以用不同的编译器来编译成可执行代码. ...

  3. Python 36 GIL全局解释器锁 、vs自定义互斥锁

    一:GIL全局解释器锁介绍 在CPython中,全局解释器锁(或GIL)是一个互斥锁, 它阻止多个本机线程同时执行Python字节码.译文:之所以需要这个锁, 主要是因为CPython的内存管理不是线 ...

  4. python基础--GIL全局解释器锁、Event事件、信号量、死锁、递归锁

    ps:python解释器有很多种,最常见的就是C python解释器 GIL全局解释器锁: GIL本质上是一把互斥锁:将并发变成串行,牺牲效率保证了数据的安全 用来阻止同一个进程下的多个线程的同时执行 ...

  5. 关于python的GIL全局解释器锁的简单理解

    GIL是解释器内部的一把锁,确切一点说是CPython解释器内部的一把锁,所以要注意区分 这和我们在Python代码中使用线程锁Lock并不是一个层面的概念. 1. GIL产生的背景: 在CPytho ...

  6. Python 之 GIL 全局解释器锁

    GIL(全局解释器锁) GIL锁即全局解释器锁,是 CPython 解释器的特性.它的作用是保证了同一时刻只有一个线程执行 Python 字节码. 它并不是 Python 的特性,它的存在是 CPyt ...

  7. python GIL全局解释器锁与互斥锁 目录

    python 并发编程 多线程 GIL全局解释器锁基本概念 python 并发编程 多线程 GIL与Lock python 并发编程 多线程 GIL与多线程

  8. python GIL全局解释器锁,多线程多进程效率比较,进程池,协程,TCP服务端实现协程

    GIL全局解释器锁 ''' python解释器: - Cpython C语言 - Jpython java ... 1.GIL: 全局解释器锁 - 翻译: 在同一个进程下开启的多线程,同一时刻只能有一 ...

  9. python并发编程-多线程实现服务端并发-GIL全局解释器锁-验证python多线程是否有用-死锁-递归锁-信号量-Event事件-线程结合队列-03

    目录 结合多线程实现服务端并发(不用socketserver模块) 服务端代码 客户端代码 CIL全局解释器锁****** 可能被问到的两个判断 与普通互斥锁的区别 验证python的多线程是否有用需 ...

随机推荐

  1. 使用NPOI,完成数据的导入导出

    解释下流程,第一步:将数据库表中的数据导出到excel表                          第二步:将excel表中的数据再插入到数据库表中(当然没有做重复性校验,测试而已)注:表结构 ...

  2. vertical-align属性baseline(转)

    图7-34 文字和图片内容默认垂直对齐方式为基线对齐 上一小节讲解了行高与单行纯文字的垂直居中,而如果行内含有图片和文字,在浏览器内浏览时,读者可以发现文字和图片在垂直方向并不是沿中线居中,而是沿基线 ...

  3. JAVA获取5位随机数

    package baofoo.utils; import org.junit.Test; import java.text.SimpleDateFormat; import java.util.Dat ...

  4. MyBatis别名

    Spring的别名管理比较规范,有严格的接口规范,SimpleAliasRegistry实现 -> AliasRegistry接口,而且是线程安全的,Map也用的是ConcurrentHashM ...

  5. [转]Tips——Chrome DevTools - 25 Tips and Tricks

    Chrome DevTools - 25 Tips and Tricks 原文地址:https://www.keycdn.com/blog/chrome-devtools 如何打开? 1.从浏览器菜单 ...

  6. unzipping/Users/xq/.gradle/wrapper /dists/gradle-3.3-all/55gk2rcmfc6p2dg9u9ohc3hw9/gradle-3.3-all.zi

    unzipping/Users/xq/.gradle/wrapper /dists/gradle-3.3-all/55gk2rcmfc6p2dg9u9ohc3hw9/gradle-3.3-all.zi ...

  7. Gulp前端服务器本地搭建

    前端服务器本地搭建分三阶段: 1.Node.js的安装 2.Npm环境配置 3.编写JS文件 1.Node.js安装: 如图所示: Next: 选择I accept 然后Next: 选择安装文件的位置 ...

  8. prince2的市场使用规模有多大?

    PRINCE2的使用和应用非常广泛.在过去的12个月里,超过60,000人参加了PRINCE2基础资格(Foundation)或从业资格(Practitioner)考试.现在每周参加考试的人数超过了2 ...

  9. 算法之冒泡排序(Java语言)

    冒泡排序(英语:Bubble Sort) 是一种简单的排序算法.它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.走访数列的工作是重复地进行直到没有再需要交换,也就是说 ...

  10. spring boot(7)-mybatis全注解化

    关于配置数据库可以参考上一篇文章,这里只讲mybatis pom.xml <!-- 引入mybatis --> <dependency> <groupId>org. ...