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. 基于jQuery日历插件制作日历

    这篇文章主要介绍了基于jQuery日历插件制作日历的相关资料,需要的朋友可以参考下 来看下最终效果图吧: 是长得丑了一点,不要吐槽我-.- 首先来说说这个日历主要的制作逻辑吧: ·一个月份最多有31天 ...

  2. AngularJS - Directive Restrictions

    While it’s cool to make a custom element like we did the the previous cast, it’s actually more commo ...

  3. 04.CSS动画示例-->烟花

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. AJAX 概念 优势 发展前景 工作原理 底层技术 状态 缺点 框架

    1. 概念 Ajax asynchronous JavaScript and XML , 异步js和xml. 这种解释已经过时了, 现在ajax就是, 允许浏览器和服务器通信, 而无需刷新当前页面的技 ...

  5. js获取上一页、当前页及域名url

    一个业务中可能会用到,跳转到另个页面后, 又后退回之前的页面,之前的页面上有个判断提示一定会出 网上搬了下代码 console.log("js获取当前域名"+window.loca ...

  6. CentOS7运维管理笔记(12)----修改主机名

    CentOS修改主机名 CentOS7和CentOS6.5 修改主机名的方法略有不同. 通过 hostname 命令可以查看当前的主机名. 1. 临时修改主机名 通过 'hostname 新的主机名' ...

  7. robbe-1.2发布-支持最新版本的friso+WinNT下php各版本的dll

    robbe是建立在friso中文分词组建上的一个高性能php中文分词扩展.(只支持UTF-8编码) robbe-1.2: 1. friso近几天发布1.3了, 接口有些许变化, 更改robbe适合最新 ...

  8. 用户登陆显示cpu、负载、内存信息

    #用户登陆显示cpu.负载.内存信息 #!/bin/bash # hostip=`ifconfig eth0 |awk -F" +|:" '/Bcast/{print $4}'` ...

  9. spring boot(1)-Hello World

    spring boot简介 spring boot是由spring官方推出的一个新框架,对spring进行了高度封装,是spring未来的发展方向.spring boot功用众多,其中最主要的功能就是 ...

  10. SQL创建视图

    1.视图的理解 从用户角度来看,一个视图是从一个特定的角度来查看数据库中的数据 .从数据库系统内部来看,一个视图是由SELECT语句组成的查询定义的虚拟表 .从数据库系统内部来看,视图是由一张或多张表 ...