GIL全局解释器锁及协程
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全局解释器锁及协程的更多相关文章
- GIL全局解释器锁、协程运用、IO模型
GIL全局解释器锁 一.什么是GIL 首先需要明确的一点是GIL并不是Python的特性,它是在实现Python解析器(CPython)时所引入的一个概念.就好比C是一套语言(语法)标准,但是可以用不 ...
- python GIL全局解释器锁,多线程多进程效率比较,进程池,协程,TCP服务端实现协程
GIL全局解释器锁 ''' python解释器: - Cpython C语言 - Jpython java ... 1.GIL: 全局解释器锁 - 翻译: 在同一个进程下开启的多线程,同一时刻只能有一 ...
- 进程、线程与GIL全局解释器锁详解
进程与线程的关系: . 线程是最小的调度单位 . 进程是最小的管理单元 . 一个进程必须至少一个线程 . 没有线程,进程也就不复存在 线程特点: 线程的并发是利用cpu上下文的切换(是并发,不是并行) ...
- Python之路-python(paramiko,进程和线程的区别,GIL全局解释器锁,线程)
一.paramiko 二.进程.与线程区别 三.python GIL全局解释器锁 四.线程 语法 join 线程锁之Lock\Rlock\信号量 将线程变为守护进程 Event事件 queue队列 生 ...
- Python自动化 【第九篇】:Python基础-线程、进程及python GIL全局解释器锁
本节内容: 进程与线程区别 线程 a) 语法 b) join c) 线程锁之Lock\Rlock\信号量 d) 将线程变为守护进程 e) Event事件 f) queue队列 g) 生 ...
- 15 GIL 全局解释器锁 C语言解决 top ps
1.GIL 全局解释器锁:保证同一时刻只有一个线程在运行. 什么是全局解释器锁GIL(Global Interpreter Lock) Python代码的执行由Python 虚拟机(也叫解释器主循环, ...
- 【转】进程、线程、 GIL全局解释器锁知识点整理
转自:https://www.cnblogs.com/alex3714/articles/5230609.html 本节内容 操作系统发展史介绍 进程.与线程区别 python GIL全局解释器锁 线 ...
- 网络编程之多线程——GIL全局解释器锁
网络编程之多线程--GIL全局解释器锁 一.引子 定义: In CPython, the global interpreter lock, or GIL, is a mutex that preven ...
- 并发编程~~~多线程~~~守护线程, 互斥锁, 死锁现象与递归锁, 信号量 (Semaphore), GIL全局解释器锁
一 守护线程 from threading import Thread import time def foo(): print(123) time.sleep(1) print('end123') ...
随机推荐
- DVWA XSS (DOM) 通关教程
DOM,全称Document Object Model,是一个平台和语言都中立的接口,可以使程序和脚本能够动态访问和更新文档的内容.结构以及样式. DOM型XSS其实是一种特殊类型的反射型XSS,它是 ...
- config 文件读取
在项目中我们经常要使用到config文件进行相应的配置,来使我们的项目更加灵活健壮. 最常见的就connetionStrings .appSettings这两个节点,那么我们怎么读取呢? 1.首先 我 ...
- oracle--数据库扩容后出现ORA-27102
一,问题描述 Connected to an idle instance. SQL> startup nomount ORA: obsolete or deprecated parameter( ...
- java ssh免密登录
package com.meituan.stabletest.sshtest; import java.io.InputStream; import com.jcraft.jsch.Channel; ...
- 微信企业号SDK
1. 微信企业号SDK class class_wxqiye { var $corpid = CorpID; var $corpsecret = CorpSecret; var $agentid = ...
- python解决自动化测试静态页面加载慢的情况
# coding:utf8from selenium import webdriverimport time # 创建一个ChromeOptions的对象option = webdriver.Chro ...
- HTML+css基础 p段落标签 a 超链接标签 Src和href有什么区别和关联? target属性 Meta标签
p段落标签: <p></p> 1.他是唯一一个可以不写结束标签的双标签. a 超链接标签: 从一个页面链接到另一个页面.靠的是href属性. Src和href有什么区别和关联 ...
- 移动端布局方案—vw+rem
前言 首先你要知道 vw 和 rem 是什么?怎么使用? ①:简单来说 vw 是视口单位,相当于把视口等分成了100,1vw = 1; ②:rem是相对单位,设置根元素 html 的 font-siz ...
- TortoiseSVN客户端更改新的URL和账号
一: 变更SVN地址 右键(TortoiseSVN) → Relocate → 输入你新的URL地址 二:变更账号 TortoiseSVN右键->Setting 进入“Setting”之后,也就 ...
- Matlab中添加语音处理(voicebox)工具箱
系统环境 win10+Matlab2017b 下载voicebox工具箱 官方下载:http://www.ee.ic.ac.uk/hp/staff/dmb/voicebox/voicebox.zip ...