GIL全局解释器锁

1、什么是GIL全局解释器锁

GIL本质是一把互斥锁,相当于执行权限,每个进程内都会存在一把GIL同一进程内的多线程,必须抢到GIL之后才能使用Cpython解释器来执行自己的代码,即同一进程下的多个线程无法实现并行,但可以实现并发

Cpython解释器下想实现并行可以开启多个进程

2、为何要有GIL

因为Cpython解释器的垃圾回收机制不是线程安全的,保证了数据的安全

3、GIL全局解释器的优缺点

优点:保证了数据安全

缺点:单个进程下开启多个线程只能实现并发不能实现并行

4、选择多进程还是多线程?

单核或多核I/O密集型下使用:多线程

单核计算密集型下使用:多线程

多核计算密集型下使用:多进程

多cpu,意味着可以有多个核并行完成计算,所以多核提升的是计算性能

每个cpu一旦遇到I/O阻塞,仍然需要等待,所以多核对I/O操作没什么用处

对于一个程序来说不可能是纯IO型或者纯计算型,我们只能相对的判断是IO密集型还是计算密集型,来选择多进程还是多线程

单核情况下:

​ 开启四个任务是计算密集型的,没有多核来并行计算,开多个进程,只是徒增进程的开销内存资源,应该使用多线程

​ 开启四个任务是IO密集型的,开启多进程也是徒增,来回切换的速度还不如开启多线程的,所以应该使用多线程

多核情况下:

​ 开启四个任务是计算密集型的,多核意味着多个CPU去计算,开启多进程可以同一时刻去计算,所以应该使用多进程

​ 开启四个任务是IO密集型的,再多的核也在在等待,来回切换的速度进程不如线程的,所以应该使用多线程

5、多线程多进程多核下性能测试

from multiprocessing import Process
from threading import Thread
import os
import time # 计算密集型
def task1():
i = 0
for line in range(110000000):
i += 1 if __name__ == '__main__':
print(os.cpu_count()) # 查看计算机几核的
list1 = []
start_time = time.time()
for i in range(4):
p1 = Process(target=task1) # 4进程下: 17.369488954544067
# t1 = Thread(target=task1) # 4线程下: 27.991361618041992
p1.start()
# t1.start()
# list1.append(t1)
list1.append(p1)
for i in list1:
i.join()
end_time = time.time()
print(end_time - start_time) # IO密集型
def task2():
time.sleep(1) if __name__ == '__main__':
print(os.cpu_count())
start_time = time.time()
list2 = []
for i in range(40):
# p2 = Process(target=task2) #40进程下: 11.374541282653809
t2 = Thread(target=task2) # 40线程下: 1.010239839553833
# p2.start()
t2.start()
# list2.append(p2)
list2.append(t2)
for i in list2:
i.join()
end_time = time.time()
print(end_time - start_time)

协程

1、什么是协程

进程:资源单位

线程:执行单位

协程:单线程下实现并发

在I/O密集型的情况下,使用协程提高执行效率

手动的实现在同一线程下 “ 遇到I/O切换+保存状态 ” 让操作系统误以为没有I/O操作,将CPU执行权限继续交给你

即:在单线程下实现多个任务遇到IO就切换可以降低单线程的IO时间,从而最大限度的提升单线程的效率

2、实现协程

gevent模块:遇到I/O自动切换并保存状态

使用gevent模块中的monkey,monkey.patch_all()来监视是否遇到IO操作,再使用spawn来创建协程,使用joinall替代join,使协程运行完再结束线程,joinall中放入得到的对象到列表中

from gevent import spawn
from gevent import joinall
from gevent import monkey
import time # 补丁:监听所有的任务是否有IO操作
monkey.patch_all() def task1(name):
print(f'{name}开始')
time.sleep(1)
print(f'{name}结束') def task2():
print('task2开始')
time.sleep(3)
print('task2结束') def task3():
print('task3开始')
time.sleep(5)
print('task3结束') if __name__ == '__main__':
start_time = time.time()
# 创建协程
sp1 = spawn(task1,'task1')
sp2 = spawn(task2)
sp3 = spawn(task3)
# sp1.join()
# sp2.join()
# sp3.join()
joinall([sp1, sp2, sp3]) # 相当于 sp.join(),注意放入列表中
end_time = time.time()
print(end_time - start_time)
# task1开始
# task2开始
# task3开始
# task1结束
# task2结束
# task3结束
# 5.013161897659302

GIL全局解释器锁及协程的更多相关文章

  1. GIL全局解释器锁、协程运用、IO模型

    GIL全局解释器锁 一.什么是GIL 首先需要明确的一点是GIL并不是Python的特性,它是在实现Python解析器(CPython)时所引入的一个概念.就好比C是一套语言(语法)标准,但是可以用不 ...

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

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

  3. 进程、线程与GIL全局解释器锁详解

    进程与线程的关系: . 线程是最小的调度单位 . 进程是最小的管理单元 . 一个进程必须至少一个线程 . 没有线程,进程也就不复存在 线程特点: 线程的并发是利用cpu上下文的切换(是并发,不是并行) ...

  4. Python之路-python(paramiko,进程和线程的区别,GIL全局解释器锁,线程)

    一.paramiko 二.进程.与线程区别 三.python GIL全局解释器锁 四.线程 语法 join 线程锁之Lock\Rlock\信号量 将线程变为守护进程 Event事件 queue队列 生 ...

  5. Python自动化 【第九篇】:Python基础-线程、进程及python GIL全局解释器锁

    本节内容: 进程与线程区别 线程 a)  语法 b)  join c)  线程锁之Lock\Rlock\信号量 d)  将线程变为守护进程 e)  Event事件 f)   queue队列 g)  生 ...

  6. 15 GIL 全局解释器锁 C语言解决 top ps

    1.GIL 全局解释器锁:保证同一时刻只有一个线程在运行. 什么是全局解释器锁GIL(Global Interpreter Lock) Python代码的执行由Python 虚拟机(也叫解释器主循环, ...

  7. 【转】进程、线程、 GIL全局解释器锁知识点整理

    转自:https://www.cnblogs.com/alex3714/articles/5230609.html 本节内容 操作系统发展史介绍 进程.与线程区别 python GIL全局解释器锁 线 ...

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

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

  9. 并发编程~~~多线程~~~守护线程, 互斥锁, 死锁现象与递归锁, 信号量 (Semaphore), GIL全局解释器锁

    一 守护线程 from threading import Thread import time def foo(): print(123) time.sleep(1) print('end123') ...

随机推荐

  1. DVWA XSS (Reflected) 通关教程

    XSS 介绍XSS,全称Cross Site Scripting,即跨站脚本攻击,某种意义上也是一种注入攻击,是指攻击者在页面中注入恶意的脚本代码,当受害者访问该页面时,恶意代码会在其浏览器上执行,需 ...

  2. 虚拟路由冗余(VRRP)协议

    1. 前言 VRRP(Virtual Router Redundancy Protocol)协议是用于实现路由器冗余的协议,最新协议在RFC3768中定义,原来的定义RFC2338被废除,新协议相对还 ...

  3. snap应用多版本卸载

    Ubuntu18.04新增了几个内置软件使用Snap格式.同样的沙箱式处理方式,除了Canonical主推的Snap,还有Fedora的Flatpak和AppImage.一般正常使用没问题,就是第一次 ...

  4. 中文情感分析——snownlp类库 源码注释及使用

    最近发现了snownlp这个库,这个类库是专门针对中文文本进行文本挖掘的. 主要功能: 中文分词(Character-Based Generative Model) 词性标注(TnT 3-gram 隐 ...

  5. [转帖]centos 7 avahi-daemon服务的作用及如何关闭

    centos 7 avahi-daemon服务的作用及如何关闭 https://blog.csdn.net/tjjingpan/article/details/81237308 关闭 systemct ...

  6. Pandas操作excel

    读取excel:Pandas库read_excel()参数详解 pandas.read_excel(io,sheet_name = 0,header = 0,names = None,index_co ...

  7. WPF 精修篇 事件触发器

    原文:WPF 精修篇 事件触发器 事件触发器 一般使用的就是动画 <Grid> <TextBlock Text="事件触发器" Opacity="0.2 ...

  8. excel批量添加超链接

    使用 Hyperlink(Link-location,Friendly-name)

  9. 关于ipad设备滚动条无法滚动的解决办法

    天做一个功能在ipad设备上滚动条无法滚动,于是百度了下,在需要产生滚动的div上面加入以下css(-webkit-overflow-scrolling:touch,overfolw:scroll), ...

  10. iTextSharp生成pdf含模板(二)---C#代码部分

    参考地址:https://www.cnblogs.com/ibeisha/p/itextsharp-pdf.html 一.先在程序中使用Nuget安装iTextSharp(我是创建的控制台程序) 二. ...