說說GIL

上一篇:線程深入篇引入

Code:https://github.com/lotapp/BaseCode/tree/master/python/5.concurrent/Thread/3.GIL

說說GIL

盡管Python完全支持多線程編程, 但是解釋器的C語言實現部分在完全并行執行時并不是線程安全的,所以這時候才引入了GIL

解釋器被一個全局解釋器鎖保護著,它確保任何時候都只有一個Python線程執行(保證C實現部分能線程安全) GIL最大的問題就是Python的多線程程序并不能利用多核CPU的優勢 (比如一個使用了多個線程的計算密集型程序只會在一個單CPU上面運行)

注意:GIL只會影響到那些嚴重依賴CPU的程序(比如計算型的)如果你的程序大部分只會涉及到I/O,比如網絡交互,那么使用多線程就很合適 ~ 因為它們大部分時間都在等待(線程被限制到同一時刻只允許一個線程執行這樣一個執行模型。GIL會根據執行的字節碼行數和時間片來釋放GIL,在遇到IO操作的時候會主動釋放權限給其他線程)

所以Python的線程更適用于處理I/O和其他需要并發執行的阻塞操作,而不是需要多處理器并行的計算密集型任務(對于IO操作來說,多進程和多線程性能差別不大)計算密集現在可以用Python的Ray框架

網上摘取一段關于IO密集和計算密集的說明:(IO密集型可以結合異步)

計算密集型任務的特點是要進行大量的計算,消耗CPU資源,比如計算圓周率、對視頻進行高清解碼等等,全靠CPU的運算能力。這種計算密集型任務雖然也可以用多任務完成,但是任務越多,花在任務切換的時間就越多,CPU執行任務的效率就越低,所以,要最高效地利用CPU,計算密集型任務同時進行的數量應當等于CPU的核心數。計算密集型任務由于主要消耗CPU資源,因此,代碼運行效率至關重要。Python這樣的腳本語言運行效率很低,完全不適合計算密集型任務。對于計算密集型任務,最好用C語言編寫。第二種任務的類型是IO密集型,涉及到網絡、磁盤IO的任務都是IO密集型任務,這類任務的特點是CPU消耗很少,任務的大部分時間都在等待IO操作完成(因為IO的速度遠遠低于CPU和內存的速度)。對于IO密集型任務,任務越多,CPU效率越高,但也有一個限度。常見的大部分任務都是IO密集型任務,比如Web應用。IO密集型任務執行期間,99%的時間都花在IO上,花在CPU上的時間很少,因此,用運行速度極快的C語言替換用Python這樣運行速度極低的腳本語言,完全無法提升運行效率。對于IO密集型任務,最合適的語言就是開發效率最高(代碼量最少)的語言,腳本語言是首選,C語言最差。

Process and Thread Test

其實用不用多進程看你需求,不要麻木使用,Linux下還好點,Win下進程開銷就有點大了(好在服務器基本上都是Linux,程序員開發環境也大多Linux了)這邊只是簡單測了個啟動時間差距就來了,其他的都不用測試了

測試Code:

from time import sleep
from multiprocessing import Processdef test(i):sleep(1)print(i)def main():t_list = [Process(target=test, args=(i, )) for i in range(1000)]for t in t_list:t.start()if __name__ == '__main__':main()

運行時間:

real    0m3.980s
user    0m2.034s
sys  0m3.119s

操作系統幾千個進程開銷還是有點大的(畢竟進程是有上線的)ulimit -a
9.MaxProcess.png

測試Code:

from time import sleep
from multiprocessing.dummy import Processdef test(i):sleep(1)print(i)def main():t_list = [Process(target=test, args=(i, )) for i in range(1000)]for t in t_list:t.start()if __name__ == '__main__':main()

運行時間:

real    0m1.130s
user    0m0.158s
sys  0m0.095s

multiprocessing.dummy里面的Process上面也說過了,就是在線程基礎上加點東西使得用起來和multiprocessingProcess編程風格基本一致(本質還是線程)

測試Code:

from time import sleep
from multiprocessing.dummy import threadingdef test(i):sleep(1)print(i)def main():t_list = [threading.Thread(target=test, args=(i, )) for i in range(1000)]for t in t_list:t.start()if __name__ == '__main__':main()

運行時間:

real    0m1.123s
user    0m0.154s
sys  0m0.085s

其實Redis就是使用單線程和多進程的經典,它的性能有目共睹。所謂性能無非看個人能否充分發揮罷了。不然就算給你轟炸機你也不會開啊?扎心不老鐵~

PS:線程和進程各有其好處,無需一棍打死,具體啥好處可以回顧之前寫的進程和線程篇~


利用共享庫來擴展

C系擴展

GIL是Python解釋器設計的歷史遺留問題,多線程編程,模型復雜,容易發生沖突,必須用鎖加以隔離,同時,又要小心死鎖的發生。Python解釋器由于設計時有GIL全局鎖,導致了多線程無法利用多核。計算密集型任務要真正利用多核,除非重寫一個不帶GIL的解釋器(PyPy)如果一定要通過多線程利用多核,可以通過C擴展來實現(Python很多模塊都是用C系列寫的,所以用C擴展也就不那么奇怪了

只要用C系列寫個簡單功能(不需要深入研究高并發),然后使用ctypes導入使用就行了:

#include <stdio.h>  void test()  
{  while(1){}
}

編譯成共享庫:gcc 2.test.c -shared -o libtest.so
9.共享庫.png

使用Python運行指定方法:(太方便了,之前一直以為C#調用C系列最方便,用完Python才知道更簡方案

from ctypes import cdll
from os import cpu_count
from multiprocessing.dummy import Pooldef main():# 加載C共享庫(動態鏈接庫)lib = cdll.LoadLibrary("./libtest.so")pool = Pool()  # 默認是系統核數pool.map_async(lib.test, range(cpu_count()))pool.close()pool.join()if __name__ == '__main__':main()

看看這時候HTOP的信息:(充分利用多核)【ctypes在調用C時會自動釋放GIL
9.ctypes.png

Go擴展

利用Go寫個死循環,然后編譯成so動態鏈接庫(共享庫):

package main
import "C"//export test
func test(){for true{}
}func main() {test()
}

非常重要的事情://export test一定要寫,不然就被自動改成其他名字(我當時被坑過)

Python調用和上面一樣:

from ctypes import cdll
from os import cpu_count
from multiprocessing.dummy import Pooldef main():# 加載動態鏈接庫lib = cdll.LoadLibrary("./libtestgo.so")pool = Pool()  # 默認是系統核數pool.map_async(lib.test, range(cpu_count()))pool.close()pool.join()if __name__ == '__main__':main()

效果:go build -buildmode=c-shared -o libtestgo.so 2.test.go
9.golang.png


題外話~如果想等CPython的GIL消失可以先看一個例子:MySQL把大鎖改成各個小鎖花了5年。在是在MySQL有專門的團隊和公司前提下,而Python完全靠社區重構就太慢了

速度方面微軟除外,更新快本來是好事,但是動不動斷層更新,這學習成本就太大了(這也是為什么Net能深入的人比較少的原因:人家剛深入一個,你就淘汰一個了...)

可能還有人不清楚,貼下官方推薦技術吧(NetCoreOrleansEFCoreML.NetCoreRT

https://github.com/aspnet/AspNetCorehttps://github.com/aspnet/EntityFrameworkCorehttps://github.com/dotnet/machinelearninghttps://github.com/dotnet/orleanshttps://github.com/aspnet/Mvchttps://github.com/dotnet/corert

課外拓展:

用go語言給python3開發模塊
https://www.jianshu.com/p/40e069954804
https://blog.filippo.io/building-python-modules-with-go-1-5Python與C/C++相互調用
https://www.cnblogs.com/apexchu/p/5015961.html使用C/C++代碼編寫Python模塊
https://www.cnblogs.com/silvermagic/p/9087896.html快速實現python c擴展模塊
https://www.cnblogs.com/chengxuyuancc/p/6374239.htmlPython的C語言擴展
https://python3-cookbook.readthedocs.io/zh_CN/latest/chapters/p15_c_extensions.htmlpython調用golang生成的so庫
https://studygolang.com/articles/10228
https://www.cnblogs.com/huangguifeng/p/8931837.htmlpython調用golang并回調
https://blog.csdn.net/gtd138/article/details/79801235Python3.x AttributeError: libtest.so: undefined symbol: fact
https://www.cnblogs.com/tanglizi/p/8965230.html

運行在其他編譯器上

先看最重要的一點,一旦運行在其他編譯器意味著很多Python第三方庫可能就不能用了,相對來說PyPy兼容性是最好的了

如果是Python2系列我推薦谷歌的grumpy

Grumpy是一個 Python to Go 源代碼轉換編譯器和運行時。旨在成為CPython2.7的近乎替代品。關鍵的區別在于它將Python源代碼編譯為Go源代碼,然后將其編譯為本機代碼,而不是字節碼。這意味著Grumpy沒有VM已編譯的Go源代碼是對Grumpy運行時的一系列調用,Go庫提供與 Python C API類似的目的

如果是Python3系列,可以使用PyPy PythonNet Jython3 ironpython3等等

PyPy:https://bitbucket.org/pypy/pypy

Net方向:

https://github.com/pythonnet/pythonnet
https://github.com/IronLanguages/ironpython3

Java方向:

https://github.com/jython/jython3

Other:

源碼:https://github.com/sbinet/go-python
參考:https://studygolang.com/articles/13019可惜CoreRT一直沒完善,不然就Happy了
https://github.com/dotnet/corert

經驗平時基本上多線程就夠用了,如果想多核利用-多進程基本上就搞定了(分布式走起)實在不行一般都是分析一下性能瓶頸在哪,然后寫個擴展庫

如果需要和其他平臺交互才考慮上面說的這些項目。如果是Web項目就更不用擔心了,現在哪個公司還不是混用?JavaScript and Python and Go or Java or NetCore。基本上上點規模的公司都會用到Python,之前都是Python and Java搭配使用,這幾年開始慢慢變成Python and Go or NetCore搭配使用了~

下集預估:Actor模型 and 消息發布/訂閱模型

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/537720.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/537720.shtml
英文地址,請注明出處:http://en.pswp.cn/news/537720.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

2021重慶高考成績名次排名查詢,重慶高考排名對應大學-重慶高考位次大學(2021年理科)...

選擇科目測一測我能上哪些大學選擇科目領取你的專屬報告>選擇省份關閉請選擇科目確定v>每年高考結束后&#xff0c;報大學、選專業、填志愿就成了考生與家長十分關心的一件事情。本期&#xff0c;圓夢志愿為大家整理了重慶高考理科2020年位次排名對應的大學&#xff0c;供…

Project項目信息的日程排定方法區別

日程排定方法分&#xff1a;項目開始日期&#xff0c;項目結束日期。 項目開始日期 設置如下 在“工期”單元格輸入任意數字&#xff0c;任務開始日期會從項目開始日期2020年3月1日開始 給項目任務設置工期的時候&#xff0c;從任務的第一個開始設置&#xff0c;按正序進行&a…

gis里創建要素面板怎么打開_周末技術流 | GIS三維熱力圖分析

周末技術流&#xff2e;&#xff2f;&#xff37;現在行動&#xff01;我們的技術流是一個系列&#xff0c;最終帶大家出一套完整圖紙哦~(未經允許嚴禁盜用&#x1f6ab;)Rhino日照分析1.前期回顧本期內容一直關注我們的朋友到這期可能會有點熟悉&#xff0c;確實&#xff0c;我…

第三章實驗二小談

第三章實驗二小談 這周很忙...時間很趕...很多作業還沒做... 首先想談&#xff08;tu&#xff09;論&#xff08;cao&#xff09;一下計算機的嚴謹性。 編程語言嚴謹是一種好事&#xff0c;越嚴謹&#xff0c;把它轉化為機器語言就越方便&#xff0c;在資源占用、運行速度等方面…

project提醒:無法鏈接這些任務,因為它們已通過另一個任務鏈鏈接

給45任務指定前置任務111時&#xff0c;提示“無法鏈接這些任務&#xff0c;因為它們已通過另一個任務鏈鏈接” 查了好久沒找到原因&#xff0c;后來無意在46任務前置任務輸入111&#xff0c;沒有提示。 解決方法&#xff1a; 刪除了提示的45任務&#xff0c;新建任務&#x…

企業網站 源碼 e-mail_天津seo優化套餐服務收費_天津網站優化關鍵詞價格

天津華陽在線專注于SEO關鍵詞排名優化&#xff0c;品牌網站建設&#xff0c;營銷型網站建設&#xff0c;App、小程序開發&#xff0c;搜索引擎seo優化&#xff0c;競價托管sem&#xff0c;品牌口碑建設與代運營等服務。企業通過引進前BAT產品經理不斷豐富產品線優化技術實力&am…

計算機網絡與綜合布線系統設計,計算機網絡與通信技術10-綜合布線系統.ppt

計算機網絡與通信技術10-綜合布線系統.ppt5.7 電氣防護系統設計 電氣防護設計應把握以下原則&#xff1a; 1)為了保證綜合布線系統正常運行&#xff0c;設備間或干線交接間內應設有獨立、穩定、可靠的交流50Hz、220V電源&#xff0c;以便于維護檢修和日常管理&#xff0c;有條件…

必須Mark下,2019 年度中國質量協會質量技術優秀獎

曾經和一群可愛的人兒做的項目&#xff0c;獲得了2019 年度中國質量協會質量技術優秀獎&#xff0c;無心插柳柳成蔭。 那幾年工作得很快樂&#xff0c;工作與家庭都兼顧&#xff0c;是同事也是朋友。2019年末去過一次移動寧波分公司&#xff0c;特意去看了原來駐場的辦公室&am…

python文件編碼及執行

兼容中文編碼 由于Python源代碼也是一個文本文件&#xff0c;所以&#xff0c;當你的源代碼中包含中文的時候&#xff0c;在保存源代碼時&#xff0c;就需要務必指定保存為UTF-8編碼。 當Python解釋器讀取源代碼時&#xff0c;為了讓它按UTF-8編碼讀取&#xff0c;我們通常在文…

html5鏈接mvc,LinkExtensions.ActionLink 方法 (System.Web.Mvc.Html) | Microsoft Docs

對于指定的鏈接文本、操作、控制器、協議、主機名、URL 片段、作為路由值字典的路由值和作為字典的 HTML 屬性&#xff0c;返回一個定位點元素&#xff0c; (元素) 。public static System.Web.Mvc.MvcHtmlString ActionLink (this System.Web.Mvc.HtmlHelper htmlHelper, stri…

這些Windows 10隱藏秘技,你知道幾個?

1. 虛擬桌面 玩電腦的老鳥&#xff0c;估計都聽說過虛擬桌面。簡言之&#xff0c;平時要做的工作太多&#xff0c;又沒有第二個顯示器&#xff0c;那么“虛擬桌面”也就成了不二之選。微軟Windows 10的虛擬桌面隱藏在WinTAB中&#xff0c;也就是所謂的時間線視圖&#xff08;T…

vant toast loading 倒計時_日期倒計時軟件哪個好 蘋果日期倒計時軟件推薦

日期倒計時軟件哪個好&#xff0c;相信大家也是經常會查看日期&#xff0c;來保證一些重要的事情能夠按時進行&#xff0c;那么哪一款日期倒計時軟件比較好用&#xff0c;能夠提醒用戶們日期將至呢。這里就為大家推薦幾款。日期倒計時軟件哪個好1.Days Matter Air作為Days Matt…

瀏覽器的差距

瀏覽器 瀏覽器默認字體是16px&#xff0c;谷歌的最小字體是12px&#xff0c;其他的是10px。 HACK Hack就是針對不同的瀏覽器去寫不同的HTML、CSS樣式&#xff0c;從而讓各瀏覽器能達到一致的渲染效果。 Hack分兩種寫法 Html的hack&#xff1a;寫在html的標簽中 Css的hack&#…

業務應用系統的業務操作日志設計

目的&#xff1a;記錄業務的訪問活動 操作時間&#xff1a;精確到秒 服務器IP&#xff1a;可能部署多臺服務器&#xff0c;記錄當前線程服務器IP地址 訪問者IP&#xff1a;訪問者ip地址 訪問者賬號&#xff1a;系統通過手機號登錄&#xff0c;記錄手機號 業務名稱&#xf…

微型計算機控制技術試卷B,微型計算機控制技術試卷b..doc

微型計算機控制技術試卷b.微型計算機控制技術試卷B一、選擇題(本題共10小題&#xff0c;每小題 1.5分&#xff0c;共15分) 1. 防止抖動是能否正確讀取鍵值的必要環節&#xff0c;實現方法是( )。 A&#xff0e;可以用硬件電路或軟件程序實現?? B&#xff0e;只能用濾波電路或…

c char轉int_c/c++基礎之sizeof用法

在 C/C 中&#xff0c;sizeof() 是一個判斷數據類型或者表達式長度的運算符。1 sizeof 定義 sizeof 是 C/C 中的一個操作符&#xff08;operator&#xff09;&#xff0c;返回一個對象或者類型所占的內存字節數。The sizeof keyword gives the amount of storage, in bytes, as…

汽車怎么保養省錢?

摘要&#xff1a;從4年4萬多公里的大保養&#xff0c;分享如何保養省錢。 如何保養省錢? 1.不花冤枉錢 2.不過度保養 3.平時用車注意 1.不花冤枉錢 除了第一次去4s店免費保養&#xff0c;第二次起就不要了。我第二、三次在朋友店里&#xff0c;第四次開始在途虎養車店。 …

非結構化數據與結構化數據提取---- BeautifulSoup4 解析器

CSS 選擇器&#xff1a;BeautifulSoup4 和 lxml 一樣&#xff0c;Beautiful Soup 也是一個HTML/XML的解析器&#xff0c;主要的功能也是如何解析和提取 HTML/XML 數據。 lxml 只會局部遍歷&#xff0c;而Beautiful Soup 是基于HTML DOM的&#xff0c;會載入整個文檔&#xff0c…

計算機的網絡技術的普及,計算機網絡技術的普及與應用-網絡技術論文-計算機論文(7頁)-原創力文檔...

計算機網絡技術的普及與應用摘要&#xff1a;隨著通信和計算機技術緊密結合與同步發展&#xff0c;我國計算機網絡技術得到飛躍的發展。如今在社會生活的各個領域都可以尋覓到計算機網絡技術的蹤跡&#xff0c;它成為社會發展中必不可少的一門技術。為進一步促進計算機網絡技術…

pyaudio usb playback_5.5寸觸控屏IP電話會議USB全向麥克風NK-OAM600U_影視工業網

寸觸控屏視頻會議USB全向麥克風(拾音器)NK-OAM600U概述&#xff1a;派尼珂NK-OAM600U視頻會議USB全向麥克風&#xff0c;是一款配置多點手勢觸控FHD屏的高清會議電話&#xff0c;便捷的連接方式&#xff1a;支持USB/以太網/WIFI/藍牙Bluetooth連接&#xff0c;同時支持外接視頻…