Cython屏蔽GIL锁实践
環境:
Ubuntu19.10
四核八線程.
題外話,八線程屬于超線程概念,程序員不可控制,屬于操作系統調度的工作.
基本概念:
什么時候使用并發/并行?
資料中有兩種說法:
一種是:
涉及到多核就是并行,單核IO異步就是并發
另一種是:
整個系統服務于IO異步任務就是并發,涉及到CPU密集就是并行
本文以第一種為準
--------------------------------
消除GIL鎖為什么會導致單線程變慢?
參考[6]的回答
Python多線程相當于單核多線程[7]
--------------------------------
網上資料的多線程包含:
單核多線程和多核多線程.
單核多線程就IO異步.
多核多線程大多數情況下指的是多核情況.
線程和并發有關系,進程和隔離有關系
根據[4]
I'd welcome a set of patches into Py3k?only if?the performance for a single-threaded program (and for a multi-threaded but I/O-bound program)?does not decrease”(這個意思是如果移除GIL鎖,那么單線程性能會下降,也就是I/O異步性能會下降)
?
Each Python process gets its own Python interpreter and memory space so the GIL won't be a problem. (每個進程都有一個GIL鎖)
網上說的"Python的多線程是雞肋"的意思指的是多核多線程
有了多線程執行異步為啥還要多協程執行IO異步?
根據[5]:
好處是協程的開銷成本更低.
?
GIL鎖影響的是IO密集還是CPU密集任務?
The GIL does not have much impact on the performance of I/O-bound multi-threaded programs as the lock is shared between threads while they are waiting for I/O.[4](影響的是CPU密集任務而不是IO密集任務)
?
GIL鎖在你調用開源庫的時候,依然存在嗎?
取決于底層是不是C寫的,如果是C寫的,屏蔽了GIL鎖,那就不存在,否則就存在
----------------------------------------------------------------------------------------------------------------------
網上關于屏蔽GIL鎖的資料如下:
[1]屏蔽了GIL鎖,沒有完整代碼
[3]講了原理,但是沒有實操
本篇博客重點解析[2].
GIL鎖每個進程都有一個,鎖的到底是什么?
鎖的是多線程進行CPU密集計算時候的場景.案例如下[4]:
單線程:
# single_threaded.py import timeCOUNT = 50000000def countdown(n):while n>0:n -= 1start = time.time() countdown(COUNT) end = time.time()print('Time taken in seconds -', end - start)Time taken in seconds - 2.2484254837036133
多線程:
Time taken in seconds - 3.074549674987793
?
多進程:
from multiprocessing import Pool import timeCOUNT = 50000000 def countdown(n):while n>0:n -= 1if __name__ == '__main__':pool = Pool(processes=2)start = time.time()r1 = pool.apply_async(countdown, [COUNT//2])r2 = pool.apply_async(countdown, [COUNT//2])pool.close()pool.join()end = time.time()print('Time taken in seconds -', end - start)結論:
CPU密集任務速度上,
多核多進程>多核多線程>單線程
----------------------------------------------下面是屏蔽GIL鎖實踐------------------------------------------------------------------------------
回到前面一個話題,python的多線程真的是雞肋嗎?
并不是,請看下面實驗,下面實驗受到[2]的啟發,但是因為[2]的代碼不完整,所以我自己想出了一個demo
我們把count提升100倍,下面是三個代碼文件:
pycall.c
#include <stdio.h> #include <stdlib.h> // #include <iostream.h> int foo(int a, int b) { long long int count=5000000000;while( count > 0 ){// cout << "a 的值:" << a << endl;count--;if(count==2500000000)printf("計數中%lld\n", count);if(count==0)printf("計數結束%lld\n", count);};printf("you input %d and %d\n", a, b); return 1; }因為我們等下要進行多線程測試,
所以我們在上面代碼中故意加入一些if語句用來監控計數過程,如果多線程生效 那么就會打印兩次,
如果GIL鎖依然存在,那么整個運行過程會比單線程還要慢一倍左右
?
pycall-1thread.py
import ctypes import threading import timeif __name__ == '__main__':start=time.time()my_lib=ctypes.cdll.LoadLibrary("./libpycall.so") t1=threading.Thread(target=my_lib.foo,args=(1,1))t1.start()t1.join()end=time.time()print('耗時=',end-start)?
pycall-2thread.py
import ctypes import threading import timeif __name__ == '__main__':start=time.time()my_lib=ctypes.cdll.LoadLibrary("./libpycall.so") t1=threading.Thread(target=my_lib.foo,args=(1,1))t2=threading.Thread(target=my_lib.foo,args=(2,2))t1.start()t2.start()t1.join()t2.join()end=time.time()print('耗時=',end-start)?
運行方法:
先生成.so文件
gcc -o libpycall.so -shared -fPIC pycall.c
然后:
| 命令 | 運行結果 |
| python pycall-1thread.py | 計數中2500000000 計數結束0 you input 1 and 1 耗時= 10.828569173812866 |
| python pycall-2thread.py | 計數中2500000000 計數中2500000000 計數結束0 you input 1 and 1 計數結束0 you input 2 and 2 耗時= 10.749252796173096 |
可以看到,雙線程運行與單線程運行速度一致,真正發揮了多核的威力.
所以明白如何使用python的多線程嗎?
在關鍵部位使用C/C++代碼來撰寫,屏蔽GIL鎖,大大提升計算速度.
C/C++寫起來如果覺得繁瑣,可以參考opencv,很多可以直接拿來用喔
?
?
Reference:
[1]Python解決GIL鎖的辦法
[2]python的GIL鎖優化方案及性能對比
[3]GIL鎖
[4]What is the Python Global Interpreter Lock (GIL)?
[5]線程和進程的區別是什么? - 無與童比的回答 - 知乎
[6]python中去掉gil會大幅降低單線程的執行速度,怎么理解?
[7]為什么有人說 Python 的多線程是雞肋呢? - DarrenChan陳馳的回答 - 知乎
[8]Python 的GIL與線程鎖
[9]Python 中的 GIL 如果可以去掉的話,是不是只要有線程鎖就完全不會產生負面影響?
[10]對于多線程程序,單核cpu與多核cpu是怎么工作的
[11]單核多線程與多核多線程的區別---總結
[12]【什么時候用多線程——CPU篇】
[13]協程池
[14]多線程有什么用?
[15]How does a single CPU handle Multi-threaded and multi-process applications?
總結
以上是生活随笔為你收集整理的Cython屏蔽GIL锁实践的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 网络大数据有风险还能在哪里网贷(网贷平台
- 下一篇: semaphore的使用