'

GIL是一个互斥锁:保证数据的安全(以牺牲效率来换取数据的安全)

阻止同一个进程内多个线程同时执行(不能并行但是能够实现并发)

并发:看起来像同时进行的

GIL全局解释器存在的原因是因为CPython解释器的内存管理不是线程安全的

垃圾回收机制

  1 引用计数

  2 标记清楚

  3 分代回收

同一个进程下的多个线程不能实现并行 但是能够实现并发 多个进程下的线程能够实现并行

'

在一个python的进程内,不仅只有主线程或者还有该主线程开启的其他线程,海有解释器开启的垃圾回收等解释器级别的线程,总之所有的线程都运行在这一个进程内。

1 所有数据都是共享的,这其中,代码作为一种数据也是被所有线程共享的(test.py的所有代码以及CPython解释器的所有
代码) 例如:test.py定义一个函数work,在进程内所有线程都能访问到work的代码,于是我们可以开启三个线程然后target都指
向该代码,能访问到意味着就是可以执行。 2 所有线程的任务,都需要将任务的代码当做参数传给解释器的代码去执行,即所有的线程想要运行自己的任务,首先需要解
决的是能够访问到解释器的代码。

综上:

如果多个线程的target=work,那么执行流程是多个线程先访问到解释器的代码,即拿到执行权限,然后将target的代码交给解释器的代码去执行解释器的代码是所有线程共享的,所以垃圾回收线程也可能放到解释器的代码而执行,这就导致了一个问题:对于同一个数据100 ,可能是线程1执行x=100的同时,而垃圾回收执行的是回收100的操作,解决这种问题就是解锁,保证python解释器同一时间只能执行一个任务的代码。

GIL全局解释锁是所有解释型语言的通病!

GIL全局解释锁是python的问题吗?

  它是CPython解释器的特点

GIL与多线程

有了GIL的存在,同一时刻同一进程中只有一个线程被执行

进程可以利用多核,但是开销大,而python的多线程开销小,但却无法利用多核优势?

  要解决这个问题,先统一一个条件:

1 cpu到底是用来做计算的,还是用来最I/O的?

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

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

一个工人相当于cpu,此时计算相当于工人在干活,I/O阻塞相当于为工人干活提供所需原材料的过程,工人干活的过程中如果没有原料了,则工人干活的过程需要停止,直到等待原材料的带来。

如果你的工厂干的大多数任务都需要准备原材料的过程(I/O密集型),那么你有再多的工人,意义也不打,还不如一个人,在等材料的过程中让工人去干别的活,

反过来讲,如果你的工厂原材料都齐全,那当然是工人越多,效率越高

结论:

  对计算来说,cpu越多越好,但是对于I/O来说,在多的cpu也没用

  当然对于运行一个程序来说,随着cpu的增多执行效率肯定会有所提高(不管提高幅度多大,总会有所提高),这是因为一个程序基本上不会是纯计算或者纯I/O,所以我们只能相对的去看一个程序到底计算密集型还是I/O密集型,从而进一步分析python的多线程到底有无用处。

我们有四个人物需要处理,处理方式肯定是要玩出并发的效果,解决方案可以是:
方案一:开启四个进程
方案二:一个进程下,开启四个线程 单核情况下,分析结果:
如果四个任务是计算密集型,没有多核来并行计算,方案一徒增了创建进程的开销,方案二胜
如果四个任务是I/O密集型,方案一创建进程的开销大,且进程的切换速度远不如线程,方案二胜 多核情况下,分析结果:
如果四个任务是计算密集型,多核意味着并行计算,在python中一个进程中同一时刻只有一个线程执行用不上多核,方案一胜
如果四个任务是I/O密集型,再多的和也解决不了I/O问题,方案二胜 结论:现在的计算机基本上都是多核,python对于计算密集型的任务开多线程的效率并不能带来多大性能上的提升,甚至不如串行(没有大量切换),但是,对于I/O密集型的任务效率还是有显著提升的。
问题:python多线程是不是就没用了?

四个任务:计算密集型的任务,每个任务耗时10s

    单核情况下:
多线程好一点,消耗的资源少一点 多核情况下:
开四个进程:10s多一点
开多线程:40s多一点 四个任务:IO密集的任务 每个任务IO 10s
单核情况下:
多线程好一点
多核情况下:
多线程好一点 多线程和多进程都有自己的优点,要根据项目需求合理现在

引用:  多线程用于IO密集型,如socket,爬虫,web

     多进程用于计算机密集型,如金融分析

多线程性能测试

#计算密集型:
from multiprocessing import Process
from threading import Thread import os,time
def work():
res=0
for i in range(10000000):
res*=i if __name__ == '__main__':
l=[]
print(os.cpu_count()) #本机为4核
start=time.time()
for i in range(4):
p = Process(target=work) #进程耗时:1.7300989627838135
# p = Thread(target=work) #线程耗时:2.648151397705078
l.append(p)
p.start() for p in l:
p.join()
stop =time.time()
print('run time is %s'%(stop-start))

计算密集型:多进程效率高

#IO密集型:
from multiprocessing import Process
from threading import Thread
import os,time def work():
time.sleep(2) if __name__ == '__main__':
l=[]
print(os.cpu_count()) #本机为4核
start=time.time()
for i in range(200):
p=Process(target=work) #进程耗时:9.763558387756348
# p=Thread(target=work) #线程耗时:2.020115852355957
l.append(p)
p.start() for p in l:
p.join()
stop=time.time()
print('run time is %s'%(stop-start))

I/O密集型:多线程效率高

GIL全局解释器的更多相关文章

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

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

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

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

  3. GIL全局解释器锁

    1. 什么是GIL全局解释器锁 GIL本质就是一把互斥锁,相当于执行权限,每个进程内都会存在一把GIL,同一进程内的多个线程     必须抢到GIL之后才能使用Cpython解释器来执行自己的代码,即 ...

  4. 网络编程-Python高级语法-GIL全局解释器锁

    知识点:GIL全局解释器锁其实和Python没有任何关系,是由于当初编写Python解释器时留下的,它只对多线程有影响,GIL保证同一时刻只有一个线程在运行,即使是多核配置电脑,同一时刻也只会让一个线 ...

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

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

  6. python GIL :全局解释器

    cpython 解释器中存在一个GIL(全局解释器锁),无论多少个线程.多少颗cpu 他的作用就是保证同一时刻只有一个线程可以执行代码,因此造成了我们使用多线程的时候无法实现并行. 因为有GIL的存在 ...

  7. [py]GIL(全局解释器锁):多线程模式

    在多线程 时同一时刻只允许一个线程来访问CPU,直到解释器遇到I/O操作或者操作次数达到一定数目时才会释放GIL 参考 Python虽然不能利用多线程实现多核任务,但可以通过多进程实现多核任务.多个P ...

  8. 10 并发编程-(线程)-GIL全局解释器锁&死锁与递归锁

    一.GIL全局解释器锁 1.引子 在Cpython解释器中,同一个进程下开启的多线程,同一时刻只能有一个线程执行,无法利用多核优势 首先需要明确的一点是GIL并不是Python的特性,它是在实现Pyt ...

  9. [Python 多线程] GIL全局解释器锁 (十三)

    Queue 标准库queue模块,提供FIFO(先进先出)的Queue.LIFO(后进先出)的队列.优先队列. Queue类是线程安全的,适用于多线程间安全的交换数据.内部使用了Lock和Condit ...

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

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

随机推荐

  1. Linux长格式文件属性介绍

    长格式文件属性 查看长格式文件命令:ll (或ls -l) (1)-:文件类型 -:普通文件 d:目录 b:块设备文件(随机读取) c:字符设备文件(顺序读取) p:管道文件 s:Socket套接字文 ...

  2. nuxt使用教程

    1 引言 Nuxt 是基于 Vue 的前端开发框架,这次我们通过 Introduction toNuxtJS 视频了解框架特色以及前端开发框架的基本要素. nuxt 与 next 结构很像,可以结合在 ...

  3. 九款Web服务器性能压力测试工具

    一.http_load 程序非常小,解压后也不到100Khttp_load以并行复用的方式运行,用以测试web服务器的吞吐量与负载.但是它不同于大多数压力测试工具,它可以以一个单一的进程运行,一般不会 ...

  4. IDEA个人常用配置记录

    原文 一.常用快捷键 编辑 ⇧ + ↩:开始新的一行 ⌘ + ⇧ + ↩:行内任意位置进行换行,并自动补齐“;”.“{}” ⌘ + ⇧ + U:大小写切换 ⌥ + ⌦:删除到单词的末尾(⌦键为Fn+D ...

  5. vue中解决three.js出现内存泄漏丢失上下文问题

    在跳转页面时添加以上代码即可. 在spa项目中,跳转页面并不会清楚已经创建的webgl实例,需要手动清楚.

  6. 小D课堂-SpringBoot 2.x微信支付在线教育网站项目实战_5-4.微信授权一键登录开发之授权URL获取

    笔记 4.微信授权一键登录开发之授权URL获取     简介:获取微信开放平台扫码连url地址 1.增加结果工具类,JsonData;  增加application.properties配置      ...

  7. Qt编写自定义控件13-多态进度条

    前言 多态进度条,顾名思义,有多重状态,其实本控件主要是用来表示百分比进度的,由于之前已经存在了百分比进度条控件,名字被霸占了,按照先来先得原则,只好另外取个别名叫做多态进度条,应用场景是,某种任务有 ...

  8. JAVA 基础编程练习题9 【程序 9 求完数】

    9 [程序 9 求完数] 题目:一个数如果恰好等于它的因子之和,这个数就称为"完数".例如 6=1+2+3.编程找出 1000 以内的 所有完数. package cskaoyan ...

  9. Delphi7-TClientDataSet: 查找

    TClientDataSet[12]: 查找 方法有:1.Locate: 根据字段列表和对应的字段值查找并定位, 找到返回 True.2.Lookup: 根据字段列表和对应的字段值查找, 返回需要的字 ...

  10. SAP JCO3配置

    windows 环境设置 1.sapjco3.dll 需要与 sapjco3.jar 在同一目录 2.设置系统环境变量,将sapjco3所在目录加入系统环境变量 例如: 新建环境变量 变量名: JAV ...