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. 01 使用Git基本方法

    什么是Git? Git是目前世界上最先进的分布式版本控制系统(没有之一). 你得先有一个Git仓库,才能进行操作.创库就是Git存放你要保存的快照的数据的地方. 拥有一个Git仓库,有两种方法. 创建 ...

  2. 二进制之Java中的进制(二)

    1. jdk中的进制转换 十进制转十六进制 Integer.toHexString(int i); 十进制转八进制 Integer.toOctalString(int i); 十进制转二进制 Inte ...

  3. 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 ...

  4. bash shell学习笔记(一)—— 常用命令

    一.基本的bash shell命令 1.默认bash shell 提示符是美元符号($); 2.bash手册 使用man命令来访问存储在Linux系统上的手册页面,如: bogon:~ Mac$ ma ...

  5. 《JavaWeb从入门到改行》fileupload,没毛病

    目录: »  fileupload API >  文件上传的要求 >  fileupload组件 »  上传细节的代码演示 »  项目案例-上传头像并显示 fileupload API 文 ...

  6. Runtime 打开记事本

    package com.direct.str; import java.io.IOException; public class RunTimeDemo { /** * @param args */ ...

  7. cf1088D. Ehab and another another xor problem(思维)

    题意 题目链接 系统中有两个数\((a, b)\),请使用\(62\)以内次询问来确定出\((a, b)\) 每次可以询问两个数\((c, d)\) 若\(a \oplus c > b \opl ...

  8. Python之面向对象继承复习

    总结:self是谁就从谁开始寻找

  9. attr()与prop()之全选、反选问题

    获取js dom原生属性的时候最好用prop()方法,获取自己添加的属性时用attr() 原文:http://blog.sina.com.cn/s/blog_bf5ce8cc0102vuyt.html ...

  10. ubuntu 14.04/14.10 iptables 防火墙设置

    1. 一键批处理设置      [plain] view plaincopyprint? #!/bin/bash PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/loc ...