gil

python GIL

拜拜、爱过 提交于 2020-03-25 12:22:38
Python并不支持真正意义上的多线程。Python中提供了多线程包,但是如果你想通过多线程提高代码的速度,使用多线程包并不是个好主意。 Python中有一个被称为Global Interpreter Lock(GIL)的东西,它会确保任何时候你的多个线程中,只有一个被执行。 线程的执行速度非常之快,会让你误以为线程是并行执行的,但是实际上都是轮流执行。经过GIL这一道关卡处理,会增加执行的开销。 这意味着,如果你想提高代码的运行速度,使用threading包并不是一个很好的方法。 不过还是有很多理由促使我们使用threading包的。如果你想同时执行一些任务,而且不考虑效率问题,那么使用这个包是完全没问题的,而且也很方便。 但是大部分情况下,并不是这么一回事,你会希望把多线程的部分外包给操作系统完成(通过开启多个进程),或者是某些调用你的Python代码的外部程序(例如Spark或Hadoop),又或者是你的Python代码调用的其他代码(例如,你可以在Python中调用C函数,用于处理开销较大的多线程工作)。 本文首发于 python黑洞网 ,博客园同步更新 来源: https://www.cnblogs.com/pythonzhilian/p/12564974.html

GIL全局解释器锁

我只是一个虾纸丫 提交于 2020-03-22 05:11:00
GIL介绍 GIL本质就是一把互斥锁,既然是互斥锁,所有互斥锁的本质都一样,都是将并发运行变成串行,以此来控制同一时间内共享数据只能被一个任务所修改,进而保证数据安全 如果多个线程的target=work,那么执行流程是: 多个线程先访问到解释器的代码,即拿到执行权限,然后将target的代码交给解释器的代码去执行 解释器的代码是所有线程共享的,所以垃圾回收线程也可能访问到解释器的代码而去执行,这就导致了一个问题:对于同一个数据100,可能线程1执行x=100的同时,而垃圾回收执行的是回收100的操作,解决这种问题没有什么高明的方法,就是加锁处理,如下图的GIL,保证python解释器同一时间只能执行一个任务的代码 GIL与Lock GIL 与Lock是两把锁,保护的数据不一样,前者是解释器级别的(当然保护的就是解释器级别的数据,比如垃圾回收的数据),后者是保护用户自己开发的应用程序的数据,很明显GIL不负责这件事,只能用户自定义加锁处理,即Lock,如下图 分析: 1、100个线程去抢GIL锁,即抢执行权限 2、肯定有一个线程先抢到GIL(暂且称为线程1),然后开始执行,一旦执行就会拿到lock.acquire() 3、极有可能线程1还未运行完毕,就有另外一个线程2抢到GIL,然后开始运行,但线程2发现互斥锁lock还未被线程1释放,于是阻塞,被迫交出执行权限,即释放GIL 4

二十八、Python之线程的GIL问题

老子叫甜甜 提交于 2020-02-27 12:54:11
1. GIL是什么 GIL(Global Interpreter Lock)并不是python的特性,而是Python解释器Cpython引入的一个概念。而python的解释器不仅仅只有Cpython,若解释器为Jpython,那么python就没有GIL。 官方的解释: In CPython, the global interpreter lock, or GIL, is a mutex that prevents multiple native threads from executing Python bytecodes at once. This lock is necessary mainly because CPython’s memory management is not thread-safe. (However, since the GIL exists, other features have grown to depend on the guarantees that it enforces.) 2.产生的原因 由于物理上得限制,各CPU厂商在核心频率上的比赛已经被多核所取代。为了更有效的利用多核处理器的性能,就出现了多线程的编程方式,而随之带来的就是线程间数据一致性和状态同步的困难。即使在CPU内部的Cache也不例外

线程,线程安全与python的GIL锁

别来无恙 提交于 2020-02-15 06:55:56
  今天看到一篇文章,讲述的是几个提升python性能的项目: 传送门   在看的过程中,接触到一个名词,一个从学python开始就一直看到,但是从来都是一知半解的名词,心里不开心,必须把它搞明白,对了,这个词就是 GIL。网上搜索了一些资料,粗浅的理解了什么是GIL,自己感觉学习的过程比较好,感觉略有收获,老规矩,为了巩固知识,自己整片文章出来写一写,其实好多文章已经写的很完善了,所以这篇随笔,只做知识巩固,如有雷同,请各位原创作者原谅,小菜鸟一枚,如果哪里写的有问题,还请各位前辈不吝指正。   一句话: 解决多线程之间数据完整性和状态同步的最简单方法自然就是加锁。   首先,GIL的全名, Global Interpreter Lock ,鉴于英文水平,不做名词翻译,以免误导。大体解释一下,这个锁就是用来为了解决Cpython多线程中线程不安全问题引入的一个全局排它锁,它的作用就是在多线程情况下,保护共享资源,为了不让多个线程同时操作共享资源,导致不可预期的结果而加上的锁,在一个线程操作共享资源时,其他线程请求该资源,只能等待GIL解锁。这个设置在Cpython刚引入多线程概念的时候就有了,然后后续的各种包和组件开发都不可避免的受到了GIL的影响,所以有人会说,python在多线程处理的时候很慢。python GIL实现方式类似于如下伪代码: if __name__ == '_

GIL全局解释器锁

拜拜、爱过 提交于 2020-02-03 22:28:10
GIL全局解释器锁 一、GIL全局解释器锁 Python代码的执行由Python虚拟机(也叫解释器主循环)来控制。 Python在设计之初就考虑到要在主循环中,同时只有一个线程在执行。 虽然 Python 解释器中可以“运行”多个线程, 但在任意时刻只有一个线程在解释器中运行。 对Python虚拟机的访问由全局解释器锁(GIL)来控制,正是这个锁能保证同一时刻只有一个线程在运行。 在多线程环境中,Python 虚拟机按以下方式执行: 设置 GIL; 切换到一个线程去运行; 运行指定数量的字节码指令或者线程主动让出控制(可以调用 time.sleep(0)); 把线程设置为睡眠状态; 解锁 GIL; 再次重复以上所有步骤。 在调用外部代码(如 C/C++扩展函数)的时候,GIL将会被锁定, 直到这个函数结束为止 (由于在这期间没有Python的字节码被运行,所以不会做线程切换)编写扩展的程序员可以主动解锁GIL。 来源: https://www.cnblogs.com/randysun/p/12257670.html

深挖 GIL锁

旧时模样 提交于 2020-02-01 21:25:15
重述 GIL 锁机制 我们知道GIL锁,它是用来保证线程安全的。 比如说,有一条代码 是 x = 10 的赋值语句,当你产生了 10 这个数值还没有进行赋值给x的时候,cpu发生了调度切换了,有可能切换到了 垃圾回收线程上,这个时候的垃圾回收线程就会发现有一个引用计数为10 的内存空间,于是就把他给释放掉了,这就导致了这条赋值语句的失败。也就造成了线程不安全的情况。 所以为了解决这个问题,就有了GIL全局解释器锁。 大白话来讲GIL锁,就是一个进程开启了,这个进程一共有3个线程,这三个线程会去抢GIL锁,只有抢到了GIL锁,解释器进程才会去执行这个线程的代码,抢到了GIL锁以后,等待cpu调度切换到了这个进程,这个进程中的线程开始执行,cpu不停地在这三个线程切换,只有其中拿到了GIL锁的线程才能被执行,其他的两个线程,就算拿到了cpu的执行权,也没有被执行。 问题 现在就有个问题,那这个拿到了GIL锁的线程什么时候才会释放GIL锁? 答案 当遇到io等待的时候,就会释放这个GIL锁。 问题二 什么是io,其实不止是增删读写文件,赋值操作也是io,关于文件的操作是磁盘io,赋值操作是内存io,因为它涉及到内存的申请了。那么他不就是在赋值的时候就释放了GIL锁了吗? 答案 内存io不会造成io等待。所以不会释放GIL锁。 总述GIL锁 1.释放GIL锁的目标,是为了释放CPU

Python Threads are not Improving Speed

时光毁灭记忆、已成空白 提交于 2020-01-30 09:33:12
问题 In order to speed up a certain list processing logic, I wrote a decorator that would 1) intercept incoming function call 2) take its input list, break it into multiple pieces 4) pass these pieces to the original function on seperate threads 5) combine output and return I thought it was a pretty neat idea, until I coded it and saw there was no change in speed! Even though I see multiple cores busy on htop, multithreaded version is actually slower than the single thread version. Does this have

running multiple threads in python, simultaneously - is it possible?

做~自己de王妃 提交于 2020-01-24 06:25:26
问题 I'm writing a little crawler that should fetch a URL multiple times, I want all of the threads to run at the same time (simultaneously). I've written a little piece of code that should do that. import thread from urllib2 import Request, urlopen, URLError, HTTPError def getPAGE(FetchAddress): attempts = 0 while attempts < 2: req = Request(FetchAddress, None) try: response = urlopen(req, timeout = 8) #fetching the url print "fetched url %s" % FetchAddress except HTTPError, e: print 'The server

python中的全局解释器锁GIL

二次信任 提交于 2020-01-22 18:25:02
全局解释器锁并不是由python语言标准规定,而是由CPython解释器实现的 产生原因: python的内存管理使用了引用计数的方法,而多线程同时操作一个变量时,引用计数可能出错导致内存泄露或者异常销毁,一个解决办法当然是加锁,但是python并没有采用,一个是频繁的加锁解锁影响性能,二是多个锁处理不好的话存在死锁的隐患,python干脆搞了一个全局的锁,GIL,任何python线程在执行之前必须获得这把唯一的解释器锁,避免了频繁加解锁和死锁。 同时也带来了问题,就是多线程无法真正利用多核。 刚才说道的是内存管理的线程安全,另外多线程间数据一致性也是问题,总之gil是为了解释器实现层面的线程安全,是当初的设计层面决定,很多人都认为这是一个烂设计,是一个历史遗留包袱。 1.python中的线程是不是操作系统内核线程,pthread? 答案是肯定的。python中的线程就是对操作系统内核线程的封装或者说是映射。一一对应。因此,python线程也是由操作系统内核进行调度的。进行调度的时机也是由操作系统来决定。 2.如果线程被操作系统调度,得到了CPU时间片,就一定会真正得到执行吗? 答案是否定的。 在解释器内部,涉及到线程执行的代码类似下面: while True r=gil.require() if r: code_line_counter=0 for code in thread

Python多线程和GIL锁

一曲冷凌霜 提交于 2020-01-20 03:10:07
Python 有GIL锁,所以它的多线程实际上是单线程 GIL 全称全局解释器锁(Global Interpreter Lock), 它锁的解释器,而不是Python代码,它防止多线程同时执行Python的字节码, 防止多线程同时访问Python的对象 Python的解释器通过切换线程的方式来模拟多线程并发的情况 那岂不是说Python多线程不会提高效率了??? 非也!!! 对于IO密集型工作,多线程可以大幅度提高效率,而对于CPU密集型工作,多线程是没用的. IO密集型 涉及到网络,磁盘IO,硬盘读写等都是IO密集型工作,这类任务对CPU的消耗较少,大部分时间不是花在代码上,而是其他操作上 CPU密集型 特点是进行大量的计算,消耗CPU资源, 比如我们常见的排序算法,对视频的解码之类的,大部分时间花在代码上 最后: CPU密集型程序适合用C等编译型语言开发的多线程, 而IO密集型程序适合Python等脚本语言开发的多线程 在使用多线程的时候,多线程爬取比单线程性能有提升,因为遇到IO阻塞会自动释放GIL锁,类似于协程. 在处理像科学计算 这类需要持续使用cpu的任务的时候 单线程会比多线程快 在 处理像IO操作等可能引起阻塞的这类任务的时候 多线程会比单线程 来源: CSDN 作者: print('hello world') 链接: https://blog.csdn.net