gil

Why are numpy calculations not affected by the global interpreter lock?

最后都变了- 提交于 2019-12-03 00:11:45
I'm trying to decide if I should use multiprocessing or threading, and I've learned some interesting bits about the Global Interpreter Lock . In this nice blog post , it seems multithreading isn't suitable for busy tasks. However, I also learned that some functionality, such as I/O or numpy, is unaffected by the GIL. Can anyone explain why, and how I can find out if my (probably quite numpy-heavy) code is going to be suitable for multithreading? mfitzp Many numpy calculations are unaffected by the GIL, but not all. While in code that does not require the Python interpreter (e.g. C libraries)

GIL锁

匿名 (未验证) 提交于 2019-12-03 00:09:02
在Cpython解释器中有一把GIL锁(全局解释器锁),GIl锁本质是一把互斥锁。 导致了同一个进程下,同一时间只能运行一个线程,无法利用多核优势. 同一个进程下多个线程只能实现并发不能实现并行. 因为cpython自带的垃圾回收机制不是线程安全的,所以要有GIL锁. 导致了同一个进程下,同一时间只能运行一个线程,无法利用多核优势. 分析:我们有四个任务需要处理,处理方式肯定是要玩出并发的效果,解决方案可以是: 方案一:开启四个进程 方案二:一个进程下,开启四个线程 每个都要计算10s 多线程 在同一时刻只有一个线程会被执行,也就意味着每个10s都不能省,分开每个都要计算10s,共40.ns 多进程 可以并行的执行多个线程,10s+开启进程的时间 4个任务每个任务90%大部分时间都在io. 每个任务io10s 0.5s 多线程 可以实现并发,每个线程io的时间不咋占用cpu, 10s + 4个任务的计算时间 多进程 可以实现并行,10s+1个任务执行的时间+开进程的时间 来源:博客园 作者: 西瓜led 链接:https://www.cnblogs.com/ledgua/p/11552227.html

GIL全局解释器锁

匿名 (未验证) 提交于 2019-12-02 23:49:02
GIL全局解释器锁1. 什么是GIL全局解释器锁 GIL本质就是一把互斥锁,相当于执行权限,每个进程内都会存在一把GIL,同一进程内的多个线程 必须抢到GIL之后才能使用Cpython解释器来执行自己的代码,即同一进程下的多个线程无法实现并行 但是可以实现并发 在Cpython解释器下,如果想实现并行可以开启多个进程2. 为何要有GIL 因为Cpython解释器的垃圾回收机制不是线程安全的3. 如何用GIL 有了GIL,应该如何处理并发进程:资源单位线程:代码的运行过程互斥锁:把多个任务对共享数据的修改,由并发变成串行,牺牲效率保证数据安全 from threading import Thread #线程 import time def task(name): print('%s is running' %name) time.sleep(2) if __name__ == '__main__': t1=Thread(target=task,args=('线程1',)) t2=Thread(target=task,args=('线程2',)) t3=Thread(target=task,args=('线程3',)) t1.start() t2.start() t3.start() 结果: 线程1 is running 线程2 is running 线程3 is running 举例

python GIL :全局解释器

匿名 (未验证) 提交于 2019-12-02 22:56:40
cpython 解释器中存在一个GIL(全局解释器锁),无论多少个线程、多少颗cpu 他的作用就是保证同一时刻只有一个线程可以执行代码,因此造成了我们使用多线程的时候无法实现并行。 因为有GIL的存在、所以同一时刻只能有一个线程被CPU执行 任务:IO 密集型:可以采用多线程(多进程+协成) 计算密集型:python不适用 (1)IO 密集型、CPU会是实现自动切换 提高工作效率 def ListenMusic(name): print ( " beging listening to %s,%s " % (name,time.ctime())) time.sleep( 5 ) print ( " end listening %s " % time.ctime()) def Recordlog(name): print ( " beging recoding to %s,%s " % (name,time.ctime())) time.sleep( 5 ) print ( " end recoding %s " % time.ctime()) if __name__ == ‘ __main__ ‘ : threads = [] t1 =threading.Thread(target=ListenMusic,args=( " 凤凰传奇 " ,)) t2 =threading

11-1 Python中的GIL

匿名 (未验证) 提交于 2019-12-02 22:51:30
GIL: global interpreter lock (cpython) GIL控制的字节码的执行,锁控制的是Python代码 什么是字节码,怎么查看字节码? #通过dis模块查看函数add的字节码 import dis def add (a) : a = a+ 1 return a print(dis.dis(add)) #运行结果 6 0 LOAD_FAST 0 (a) 2 LOAD_CONST 1 ( 1 ) 4 BINARY_ADD 6 STORE_FAST 0 (a) 7 8 LOAD_FAST 0 (a) 10 RETURN_VALUE 2.GIL作用 GIL使得同一时刻只有一个线程在一个cpu上执行字节码。保证字节码的执行是线程安全的 有了GIL是不是就是多线程安全的,不需要考虑线程间同步呢? 答案肯定不是的,因为GIL会在适当的时候释放的。举例说明 total= 0 def add () : #1. dosomething1 #2. io操作 #3. dosomething3 global total for i in range( 1000000 ): total += 1 def desc () : global total for i in range( 1000000 ): total -= 1 import threading thread1

Python GIL锁

匿名 (未验证) 提交于 2019-12-02 22:51:30
Cpython进程与其运行文件所产生的主进程是一个进程(文件进程相当于Cpython的一个线程)线程的特点是数据资源是共享的,而多个线程又都要共享Cpython的解释权限,共享意味着竞争,有竞争数据就不安全,所以Cpython的GIL锁(Cpython的一个线程)就产生了,根本作用是,当python文件中的线程想要执行其代码,必须获得GIL权限,否则不能执行,所以cpu的多核优势也没有了,除非多开Cpython解释器或多进程,否则同时只能运行一个线程 一个工人相当于cpu,此时计算相当于工人在干活,I/O阻塞相当于为工人干活提供所需原材料的过程,工人干活的过程中如果没有原材料了,则工人干活的过程需要停止,直到等待原材料的到来。 如果你的工厂干的大多数任务都要有准备原材料的过程(I/O密集型),那么你有再多的工人,意义也不大,还不如一个人,在等材料的过程中让工人去干别的活, 反过来讲,如果你的工厂原材料都齐全,那当然是工人越多,效率越高 结论:   对计算来说,cpu越多越好,但是对于I/O来说,再多的cpu也没用   当然对运行一个程序来说,随着cpu的增多执行效率肯定会有所提高(不管提高幅度多大,总会有所提高),这是因为一个程序基本上不会是纯计算或者纯I/O,所以我们只能相对的去看一个程序到底是计算密集型还是I/O密集型,从而进一步分析python的多线程到底有无用武之地。

python GIL锁与多cpu

狂风中的少年 提交于 2019-12-02 18:35:06
多核CPU 如果你不幸拥有一个多核CPU,你肯定在想,多核应该可以同时执行多个线程。 如果写一个死循环的话,会出现什么情况呢? 打开Mac OS X的Activity Monitor,或者Windows的Task Manager,都可以监控某个进程的CPU使用率。 我们可以监控到一个死循环线程会100%占用一个CPU。如果有两个死循环线程,在多核CPU中,可以监控到会占用200%的CPU,也就是占用两个CPU核心。要想把N核CPU的核心全部跑满,就必须启动N个死循环线程。 试试用Python写个死循环: ? 1 2 3 4 5 6 7 8 9 10 import threading, multiprocessing def loop(): x = 0 while True : x = x ^ 1 for i in range (multiprocessing.cpu_count()): t = threading.Thread(target = loop) t.start() 启动与CPU核心数量相同的N个线程,在4核CPU上可以监控到CPU占用率仅有102%,也就是仅使用了一核。 但是用C、C++或Java来改写相同的死循环,直接可以把全部核心跑满,4核就跑到400%,8核就跑到800%,为什么Python不行呢? 因为Python的线程虽然是真正的线程,但解释器执行代码时

Using a dictionary in Cython , especially inside nogil

蓝咒 提交于 2019-12-02 17:20:25
I am having a dictionary, my_dict = {'a':[1,2,3], 'b':[4,5] , 'c':[7,1,2]) I want to use this dictionary inside a Cython nogil function . So , I tried to declare it as cdef dict cy_dict = my_dict Up to this stage is fine. Now I need to iterate over the keys of my_dict and if the values are in list, iterate over it. In Python , it is quite easy as follows: for key in my_dict: if isinstance(my_dict[key], (list, tuple)): ###### Iterate over the value of the list or tuple for value in list: ## Do some over operation. But, inside Cython, I want to implement the same that too inside nogil . As,

day30总结

青春壹個敷衍的年華 提交于 2019-12-02 16:02:08
目录 多线程实现TCP服务端并发 服务端---封装接口思想 GIL全局解释器锁 什么是GIL?---global interpreter lock 为什么要有GIL? 死锁问题及解决 死锁问题 解决:递归锁 信号量 多线程实现TCP服务端并发 服务端---封装接口思想 import threading import socket def server_interface(): server = socket.socket() server.bind(('127.0.0.1', 8888)) server.listen() def multi_handle(): new_server_link, address = server.accept() print(address) while True: try: res = new_server_link.recv(1024).decode('utf-8') print(res) new_server_link.send(res.upper().encode('utf-8')) if res == 'q': return except Exception as e: print(e) return for i in range(10): t = threading.Thread(target=multi_handle) t.start(

python中的GIL锁与线程互斥锁的区别

陌路散爱 提交于 2019-12-02 15:08:59
python中的GIL锁与线程互斥锁的区别 GIL锁: GIL的全称是Global Interpreter Lock(全局解释器锁),来源是python设计之初的考虑,为了数据安全所做的决定。某个线程想要执行,必须先拿到GIL,我们可以把GIL看作是“通行证”,并且在一个python进程中,GIL只有一个。拿不到通行证的线程,就不允许进入CPU执行。GIL只在cpython中才有。 互斥锁 那么多线程编程时通过调用threading模块的Lock函数,来获取一把互斥锁。 互斥锁就是对共享数据进行锁定,保证同一时刻只有一个线程操作数据。 GIL锁的释放 在python3.x中,GIL不使用ticks计数,改为使用计时器(执行时间达到阈值后,当前线程释放GIL),这样对CPU密集型程序更加友好,但依然没有解决GIL导致的同一时间只能执行一个线程的问题,所以效率依然不尽如人意。 那么下来用代码来解释互斥锁与GIL锁的区别 假设有这样一个场景: import threading # 定义全局变量 g_num = 0 # 循环一次给全局变量加1 def sum_num1 ( ) : for i in range ( 1000000 ) : global g_num g_num += 1 print ( "sum1:" , g_num ) # 循环一次给全局变量加1 def sum_num2