[ Python - 11 ] 多线程及GIL全局锁
1. GIL是什么?
首先需要明确的一点是GIL并不是python的特性, 它是在实现python解析器(Cpython)时所引入的一个概念。
而Cpython是大部分环境下默认的python执行环境,要明确一点:GIL并不是python的特性,python完全可以不依赖于GIL。
2. 为什么会有GIL?
为了更有效的利用多核处理器的性能,就出现了多线程的编程方式,而随之带来的就是线程间数据的一致性和状态同步的完整性
(例如:线程2需要线程1执行完成的结果,然而线程2又比线程1代码量少,线程2执行完成,线程1仍然还在执行,这就是数据的同步性)
python为了利用多核,开始支持多线程,而解决多线程之间数据完整性和状态同步最简单的方式就是加锁。
3. GIL的影响
GIL无疑就是一把全局排它锁,全局锁的存在会对多线程的效率有不小的影响。甚至就几乎等于python是个单线程的程序。
下面通过实例来测试python单线程和多线程:
win7 python3.0+ #!_*_coding:utf-8_*_
# Author: hkey
import threading, time
def run_thread():
n = 0
while n <= 100000000:
n += 1 def single_run():
start_time = time.time()
for i in range(4):
t = threading.Thread(target=run_thread,)
t.start()
t.join() # 四个线程串行执行
print('single thread times:', time.time()-start_time)
def multi_run():
thread_list = []
start_time = time.time()
for i in range(4):
t = threading.Thread(target=run_thread,)
t.start()
thread_list.append(t)
for t in thread_list:
t.join() # 四个线程并行执行
print('multi threads times:', time.time()-start_time) if __name__ == '__main__':
single_run()
multi_run()
# 线程的串行和并行是通过join()方法来确定的,join方法是阻塞当前线程并等待正在执行的子线程执行完毕。
执行结果:
single thread times: 28.13599991798401
multi threads times: 29.76200008392334
通过结果可以发现,单线程串行执行效率和多线程并发相比要快,这也证明了GIL全局锁的存在
4. python多线程并行执行原理
在双核cpu主机上,两个线程均为CPU密集型运算线程,这里假设每个线程单独占用一核cpu,因为GIL锁的缘故,
同一时间片就只能有一个线程获得GIL全局锁,而另一个占用cpu的线程则无法执行,继续等待,cpu时间就白白浪费掉,
也就是只有获得GIL锁的线程才能真正在cpu上运行。所以,多线程在python中只能交替执行,即使100个线程跑在100核cpu上,也只能用到1核。
5. 如何避免受到GIL的影响
既然python的多线程在多核主机上这么鸡肋,那有什么更好的方式实现多并发吗?
用进程+协程 代替 多线程的方式
在多进程中,由于每个进程都是独立的存在,所以每个进程内的线程都拥有独立的GIL锁,互不影响。
但是,由于进程之间是独立的存在,所以进程间通信就需要通过队列的方式来实现。
[ Python - 11 ] 多线程及GIL全局锁的更多相关文章
- python GIL 全局锁,多核cpu下的多线程性能究竟如何?
python GIL 全局锁,多核cpu下的多线程性能究竟如何?GIL全称Global Interpreter Lock GIL是什么? 首先需要明确的一点是GIL并不是Python的特性,它是在实现 ...
- 并发编程-线程-死锁现象-GIL全局锁-线程池
一堆锁 死锁现象 (重点) 死锁指的是某个资源被占用后,一直得不到释放,导致其他需要这个资源的线程进入阻塞状态. 产生死锁的情况 对同一把互斥锁加了多次 一个共享资源,要访问必须同时具备多把锁,但是这 ...
- python多线程和GIL全局解释器锁
1.线程 线程被称为轻量级进程,是最小执行单元,系统调度的单位.线程切换需要的资源一般,效率一般. 2.多线程 在单个程序中同时运行多个线程完成不同的工作,称为多线程 3.并 ...
- Python高级笔记(一) -- GIL (全局解释器锁)
1. GIL概念 (cpython历史遗留问题) 概念? 对Python多线程的影响? 编写一个多线程抓取网页的程序? 阐述多线程抓取程序是否比单线程性能有提升, 并解释原因. GIL:全局解释器锁, ...
- TCP并发、GIL全局锁、多线程讨论
TCP实现并发 #client客户端 import socket client = socket.socket() client.connect(('127.0.0.1',8080)) while T ...
- python网络编程--线程GIL(全局解释器锁)
一:什么是GIL 在CPython,全局解释器锁,或GIL,是一个互斥体防止多个本地线程执行同时修改同一个代码.这把锁是必要的主要是因为当前的内存管理不是线程安全的.(然而,由于GIL存在,其他特性已 ...
- Python-多线程之消费者模式和GIL全局锁
一.生产者和消费者模式 什么是生产者消费者模式 生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题.生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯, 所以生产者生产完数据之后不 ...
- GIL全局锁测试
基础知识:https://www.cnblogs.com/SuKiWX/p/8804974.html 测试环境 python3.7默认解释器(cpython) cpu为四核 测试代码 #! /usr/ ...
- [py]GIL(全局解释器锁):多线程模式
在多线程 时同一时刻只允许一个线程来访问CPU,直到解释器遇到I/O操作或者操作次数达到一定数目时才会释放GIL 参考 Python虽然不能利用多线程实现多核任务,但可以通过多进程实现多核任务.多个P ...
随机推荐
- 什么是http?
http请求流程: http课程链接:http://www.imooc.com/video/6712/0
- markdown(自己看)
https://www.cnblogs.com/james-lee/p/6847906.html https://maxiang.io/
- ASP.NET CORE 2.0 文档中文正式版已经出来了
https://docs.microsoft.com/zh-cn/aspnet/core/
- java--List转换成json格式
方法一 首先导入jar包,json-rpc-1.0.jar public class List2Json { public static JSONArray ProLogList2Json(List& ...
- xml解析标签
//获取两个标签之间的值 private static string GetStr(string message, string strStart, string strEnd) { ; ; star ...
- iOS-显示日期的转换,今天,昨天,前天
+ (NSString *)stringWithDate:(NSDate *)date{ // 1.获得年月日 NSCalendar *calendar = [NSCalendar currentCa ...
- PAT 1055 集体照
https://pintia.cn/problem-sets/994805260223102976/problems/994805272021680128 拍集体照时队形很重要,这里对给定的 N 个人 ...
- Linux挂载Win共享文件夹 一
1, Win下选中文件夹,属性设置为共享,红圈中的为共享路径,挂载时//ip/共享路径 2, 3,Linux需要安装这两个软件 rpm -qa | grep samba-client rpm -qa ...
- Java学习全攻略-->阅读官方文档
一直感觉Java的官方文档有些杂乱,最近特意整理了一下,仅供参考. 入口 Oracle官方文档入口:http://docs.oracle.com/.下级页面这边只整理了JavaEE跟JavaSE的文档 ...
- bzoj3011 可并堆
我们可以遍历得出每个节点到根节点的距离h,然后用可并堆进行维护.树形dp 我用的是pairing heap #include<cstdio> #include<algorithm&g ...