尹立博:Python 全局解釋器鎖與並發 | AI 研習社第 59 期猿桌會

2021-01-07 雷鋒網

雷鋒網 AI 科技評論按:作為排名靠前的最受歡迎和增長最快的程式語言之一,Python 是一種多用途、高級別、面向對象、交互式、解釋型和對用戶非常友好的程式語言,擁有卓越的可讀性和極高的自由度。而為了能利用多核多線程的的優勢,同時又要保證線程之間數據完整性和狀態同步,Python 官方的、最廣泛使用的解釋器——CPython 往往會採取最簡單的加鎖的方式——全局解釋器鎖(GIL)。

然而,GIL 的設計有時會顯得笨拙低效,並對語言的並發性帶來嚴重限制,但是此時由於內置庫和第三方庫已經對 GIL 形成了巨大的依賴,想改變 GIL 反而變得困難了。不過實際上,Python 生態系統中存在諸多工具可以解決這一問題。

近日,在雷鋒網 AI 研習社公開課上,畢業於澳大利亞國立大學的尹立博介紹了全局解釋器鎖(GIL)和提升並發性的不同思路。公開課回放視頻網址:http://www.mooc.ai/open/course/569?=aitechtalkyinlibo

尹立博:畢業於西澳大利亞大學和澳大利亞國立大學。現在坎培拉 Seeing Machines 公司擔任數據分析師,日常使用 Python 數據工具對大量時序數據進行管理、分析與可視化開發。

分享主題:Python 全局解釋器鎖與並發

分享提綱:

1、全局解釋器鎖 (GIL)

2、多進程 (multiprocessing)

3、多線程 (multithreading)

4、異步 (async)

5、分布式計算(以 Dask 為例)

雷鋒網 AI 研習社將其分享內容整理如下:

今天要跟大家分享的是 Python 全局解釋器鎖與並發。我會先介紹一下全局解釋器鎖 (GIL))的概念和影響;接下來會藉助幾個案例分析來展示 Python 通過多進程、多線程和異步、分布式計算來達成並發的幾種方式;最後會介紹一套分布式計算工具——Dask。

全局解釋器鎖 (GIL)

GIL 的概念用簡單的一句話來解釋,就是「任一時刻,無論線程多少,單一 CPython 解釋器只能執行一條字節碼」。這個定義需要注意的點包括:

第一,GIL 不屬於 Python 語言定義,而是 CPython 解釋器實現的一部分;

第二,其他 Python 解釋器不一定有 GIL。例如 Jython (JVM) 和 IronPython (CLR) 沒有 GIL,而 PyPy 有 GIL;

第三,GIL 並不是 Python 的專利。其他語言也有 GIL,尤其是動態語言,如 Ruby MRI。

說到 GIL,就不得不提 Python 線程模型,它的運行方式如下:

CPython 使用 OS 原生線程,由 OS 負責調度;

每個解釋器進程有唯一的主線程和用戶定義的任意數量子線程;

GIL 是字節碼層面上的互斥鎖。剛剛定義中提到的 PyThread_type_lock 就是 OS 互斥鎖的別名

每個解釋器進程有且僅有一把鎖;

當解釋器啟動時,主線程即獲取 GIL;

一個線程持有 GIL 並執行字節碼時,其他線程處於阻塞狀態。

GIL 被加到 CPython 解釋器中,是有其原因的。在 1992 年,單 CPU 是合理的假設!多核則是 2005-2006 年前後才普及,此外,GIL 的優勢還包括:

簡化解釋器實現;

優化單進程性能;

簡化 C 擴展庫的整合。

Python 有兩種多任務模型:一種叫做協作式 (cooperative) 多任務;另一種叫搶佔式 (preemptive) 多任務。

協作式多任務:

搶佔式多任務:

接下來可以進展到去除 GIL。這是很多 Python 用戶十分期待的事情,但是短期內是不太可能實現的,它的難點包括:

第一,技術問題

Guido 要求不降低單線程執行效率

兼容現有引用計數與垃圾回收機制

兼容現有 C 擴展

第二,在社區友好性上,不顯著提高開發難度。

儘管如此,我們也可以看到一些現有去除 GIL 的實驗性的方案:

Gilectomy:嘗試將 GIL 換成若干小鎖,然而這種方案嚴重降低了 Python 的性能。首先,它會使得多線程競爭同一把鎖。其次,它在將 GIL 換成若干小鎖後,將嚴重降低緩存的命中率。

PyPy:實驗性分支支持軟體事務內存 (STM),不過 STM 目前還是一個相對少見的機制,可解決當前很多問題,但是實現非常困難——尤其在像 Python 這種高度動態的語言當中。

Starlark:這種方案並非去掉 GIL,而是一門兼容部分 Python 語法,並發執行字節碼的新語言。它目前用於 Google Bazel 編譯系統,我個人認為這是一個非常有意思的未來趨勢。

既然現在去除 GIL 的方案都有很多弊端,並且短期內我們也無法讓 GIL 從 Python 中被去除,我們最常見的解決方案就是避開 GIL,主要通過兩種手段實現:

第一種是多解釋器進程並發 (multiprocessing)

第二種是避免執行 Python 字節碼,常見的方法有:Cython ctypes、部分 NumPy 函數釋放 GIL、Numba JIT「nogil=True」,以及 TensorFlow/PyTorch JIT。

多進程(multiprocessing)和多線程(multithreading)

進入案例分析前,先介紹幾個相關的概念。

首先介紹一下並行與並發的區別:

並發(concurrency):是指多個操作可以在重疊的時間段內進行,例如在第一個時間片內,線程 A 執行,線程 B 阻塞;第二個時間片內,線程 B 等待 I/O,而線程 A 執行;第三個時間片內,線程 A 執行,而線程 B 還在等待 I/O。

並行(parallelism):是指多個操作在同一時間點上進行。無論在哪個時間片裡,兩個線程可能同時處於某一狀態。例如在第一個時間片內,線程 A 執行,線程 B 執行;第二個時間片內,線程 A 等待 I/O,線程 B 也在等待 I/O ;第三個時間片內,線程 A 執行,而線程 B 也 執行。

多線程意味著我們在使用並發這種線程模型,而多進程則是在使用並行這一線程模型,其各有利弊:

接下來我們將通過一個案例來嘗試 Python 並發的幾種不同解決方案的案例:

(關於嘗試 Python 並發的幾種不同解決方案的案例講解,請回看視頻 00:19:05 處,http://www.mooc.ai/open/course/569?=aitechtalkyinlibo

這就講到多進程(multiprocessing)這一概念,它的適用場景包括:

CPU 佔用率高

子進程間通信簡單

相關變量和函數可被序列化,但佔用內存較小

如果想知道更多內容,大家可參見文檔:

https://docs.python.org/3/library/multiprocessing.html

https://docs.python.org/3/library/concurrent.futures.html

接下來進入到多進程解決方案的案例講解:

(關於多進程解決方案的案例講解,請回看視頻 00:23:25 處,http://www.mooc.ai/open/course/569?=aitechtalkyinlibo

之後要講到多線程 (multithreading),多線程的使用場景包括:

如要了解更多內容,可以參見文檔:

https://docs.python.org/3/library/threading.html

https://docs.python.org/3/library/queue.html

(關於多線程解決方案的案例講解,請回看視頻 00:33:25 處,http://www.mooc.ai/open/course/569?=aitechtalkyinlibo

再看一下 Python 多線程編程難點,下面這些難點有些針對 Python,有些是所有多線程共通的難題:

第一,CPython 的線程切換可能在任意字節碼之間發生,而 Python 指令不具有原子性

第二,每次訪問受限資源都需獲取鎖

第三,鎖不具有強制性,即使忘記獲取鎖,代碼也可能運行

第四,競爭狀態難以複製

我們看一個相關的案例——多線程計數器:

(關於多線程計數器的案例講解,請回看視頻 00:37:00 處,http://www.mooc.ai/open/course/569?=aitechtalkyinlibo

異步 (async)

接著講一下異步 (async)。Python 中的異步是一種在單一線程內使用生成器實現的協程,比線程能更高效地組織非阻塞式任務。協程的切換由 Python 解釋器內完成。當然,其他語言也有異步編程,比如 Go 語言的 goroutine,以及 Nginx 用 C 實現了異步編程。

關於更多異步編程的內容,大家可參見文檔:

https://docs.python.org/3/library/asyncio-task.html

看案例之前,先比較一下異步與線程。與線程相比,異步的優劣勢分別為:

優勢:

簡單的多任務模型

明確的協程切換點

系統開銷遠小於 OS 原生線程

劣勢:

有相對獨立的生態系統

與其他並發模型混用較難

API 仍未穩定

下面我們看異步的案例:

(關於異步的案例講解,請回看視頻 00:46:05 處,http://www.mooc.ai/open/course/569?=aitechtalkyinlibo

分布式計算(以 Dask 為例)

最後講一下分布式計算,本堂課中的分布式計算以 Dask 為例。

Dask 是一種基於運算圖的動態任務調度器,可使用動態調度器擴展 NumPy 和 Pandas。左邊這個圖就是 Dask 的運算圖。

(關於 Dask 運算圖的講解,請回看視頻 00:55:45 處,http://www.mooc.ai/open/course/569?=aitechtalkyinlibo)

與另一種分布式計算方法 Spark 比較,Dask 的特性非常鮮明:

它是一個純 Python 實現

無需遵循 map-reduce 範式

細粒調度帶來較低的延遲

在 Dask 中,我們更關注的是 Distributed。它是 Dask 在異構集群上的擴展。它的網絡結構遵循客戶 – 調度器 – 工作節點這樣的形式,因此要求所有節點擁有相同的 Python 運行環境。

接下來我們看一個簡單的案例:

(關於該案例講解,請回看視頻 00:59:45 處,http://www.mooc.ai/open/course/569?=aitechtalkyinlibo

最後放上今天這堂課涉及到的內容的演講,基本都能在 youtube 上進行觀看。

Dave Beazley: Understanding the Python GIL, PyCon 2010 

https://www.youtube.com/watch?v=Obt-vMVdM8s 

https://www.dabeaz.com/python/UnderstandingGIL.pdf 

Dave Beazley: Embracing the Global Interpreter Lock (GIL), PyCodeConf 2011

https://www.youtube.com/watch?v=fwzPF2JLoeU 

Larry Hastings: Python's Infamous GIL, PyCon 2015 

https://www.youtube.com/watch?v=KVKufdTphKs 

Larry Hastings: Removing Python's GIL: The Gilectomy, PyCon 2016 

https://www.youtube.com/watch?v=P3AyI_u66Bw

A Jesse Jiryu Davis: Grok the GIL Write Fast And Thread Safe Python, PyCon 2017

https://www.youtube.com/watch?v=7SSYhuk5hmc

Raymond Hettinger: Keynote on Concurrency, PyBay 2017

https://www.youtube.com/watch?v=9zinZmE3Ogk 

https://pybay.com/site_media/slides/raymond2017-keynote/index.html 

Dave Beazley: Fear and Awaiting in Async: A Savage Journey to the Heart of the Coroutine Dream

https://www.youtube.com/watch?v=E-1Y4kSsAFc 

Robert Smallshire: Coroutine Concurrency in Python 3 with asyncio 

https://www.youtube.com/watch?v=c5wodlqGK-M •Matthew Rocklin: Dask for ad hoc distributed computing 

https://www.youtube.com/watch?v=EEfI-11itn0 

Matthew Rocklin: Dask: A Pythonic Distributed Data Science Framework, PyCon 2017 

https://www.youtube.com/watch?v=RA_2qdipVng

以上就是本期嘉賓的全部分享內容。更多公開課視頻請到雷鋒網(公眾號:雷鋒網) AI 研習社社區(http://ai.yanxishe.com/)觀看。關注微信公眾號:AI 研習社(okweiwu),可獲取最新公開課直播時間預告。

雷鋒網原創文章,未經授權禁止轉載。詳情見轉載須知。

相關焦點

  • Laura:AI 字幕翻譯經驗分享 | AI研習社第 52 期猿桌會
    近日,在雷鋒網 AI 研習社公開課上,上海外國語大學英語專業碩士畢業、目前長期從事專職英語翻譯的 Laura  就從自己英語翻譯的專業背景出發,從實戰的角度,分享 AI 字幕翻譯的技巧,希望幫助更多同學事半功倍地做好字幕翻譯。
  • 竹間智能翁嘉頎:人機互動技術探索 | AI 研習社 60 期猿桌會
    近日,在雷鋒網 AI 研習社公開課上,竹間智能 CTO 翁嘉頎分享了人機互動技術探索。公開課回放視頻網址:http://www.mooc.ai/open/course/587?分享主題:人機互動技術探索分享提綱:情感計算、意圖、主題、上下文、中文 NLP 應用、多輪對話、算法與數據的關係雷鋒網 AI 研習社將其分享內容整理如下:今天講的主題是人機互動技術探索,我會著重講這些技術的應用以及怎樣解決當前的問題
  • 2018 公開課盤點應用篇:面向 AI 開發者,「猿桌會」帶你看各路大神...
    研習社又為大家呈上了一系列公開課,AI 研習社的粉絲們也再度與我們相伴走過了一年。作為一個針對 AI 開發者的公開課類目,「猿桌會」自去年推出以來廣受各位的喜愛,在今年雷鋒網 AI 研習社依舊以最飽滿的誠意為大家邀請了領域內的各路大神進行分享,具體內容涵蓋深度學習開源框架、神經網絡調參和優化、開發語言使用技巧、開源工具使用心得、人工智慧/數據競賽經驗、 行業最新成果等,持續關注我們公開課的粉絲們想必也從他們身上得到了不少收穫。
  • 聖路易斯華盛頓大學劉晨:室內場景的結構化重建 | AI研習社68期大...
    AI研習社按:隨著增強現實,家務機器人等應用的普及,室內場景重建研究正在得到越來越廣泛的關注。在本次AI研習社大講堂上,來自聖路易斯華盛頓大學的計算機系在讀博士劉晨分享了其結構化重建的最新工作。分享嘉賓:劉晨,聖路易斯華盛頓大學計算機系在讀博士,導師是Yasutaka Furukawa教授,主要研究方向為三維視覺,場景理解等。其研究工作曾在 CVPR、ICCV、ECCV等會議發表。
  • 清華大學豈凡超:義原的介紹和義原的自動推薦 | AI 研習社第 76 期...
    近日,在雷鋒網 AI 研習社公開課上,清華大學計算機系在讀博士豈凡超就分享了採用機器學習的方法為中文新詞自動推薦義原,並進一步為其他語言的詞語推薦義原。公開課回放視頻網址:http://www.mooc.ai/open/course/555?
  • 清華大學柯沛:閒聊對話中的句式控制 | AI研習社65期大講堂
    在近日的 AI 研習社大講堂上,柯沛給我們介紹了這項具有開創性的研究成果。基於條件變分自編碼器的對話生成模型生成質量的自動評價和人工評測未來工作及展望雷鋒網AI研習社將其分享內容整理如下:很高興能有機會跟大家分享我們的工作,我叫柯沛,是清華大學計算機系的在讀博士生
  • ...AI研習社定製雙肩包和保溫杯?邀請朋友學習「CMU 深度學習課程...
    自 AI 研習社「小組」產品上線以來,收穫了很多社區用戶的支持,同時也得到了大量的意見和建議。所以,為了幫助社區用戶認識更多有技術有想法的朋友,為了讓社區用戶更好地相互學習,AI 研習社決定發起「邀朋友,送福利」活動 —— 自本文發布之時起,到 11 月 26 日(下周一)晚 12 點為止,小組邀請榜單前 15 名用戶將會獲得 AI 研習社提供的大量福利獎品。
  • 香港中文大學胡梟瑋:用於陰影檢測的 DSC 特徵 | AI研習社64期大...
    來自香港中文大學的胡梟瑋採用了提取 DSC 特徵的方式來解決這個問題,他在近日的 AI 研習社大講堂上向我們分享了具體操作思路。公開課回放地址:http://www.mooc.ai/open/course/523 分享主題:用於陰影檢測的 DSC 特徵分享提綱:陰影檢測相關工作與研究動機DSC模型介紹實驗結果與討論最新工作---陰影去除
  • 清華大學韓旭:神經關係抽取模型 | AI研習社71期大講堂
    雷鋒網AI研習社按:關係抽取是自然語言處理中的重要任務,也是從文本中挖掘知識的基本途徑之一。深度學習在關係抽取中的研究在近幾年取得了廣泛關注,其中基於遠距離監督、帶有注意力機制的神經網絡模型成為解決問題的主要方法。在本次公開課中,講者將梳理神經模型在關係抽取中的發展脈絡,並分享相關領域的最新工作進展。
  • 下個10 年,Go 能取代 Python 成為開發者的首選語言嗎?
    速度Python 是一種解釋型語言,這也導致了它最大的問題 —— 運行緩慢。與其他語言(例如 C++、Java)相比,Python 的運行速度非常慢。此外,Python 還是一種動態型語言。變量的數據類型在運行期間自動分配,這也使得運行速度大大降低。
  • 鄒炎炎:語義分析介紹及跨語言信息在語義分析中的應用 | AI 研習社...
    雷鋒網 AI 研習社編者按:語義分析(semantic parsing)是人工智慧的一個分支,是自然語言處理技術的幾個核心任務,涉及語言學、計算語言學、機器學習,以及認知語言等多個學科。近年來,隨著人工智慧的發展,語義分析也越發重要。
  • 香港中文大學胡梟瑋:用於陰影檢測的 DSC 特徵 | AI研習社64期大講堂
    雷鋒網AI研習社按:陰影檢測向來是計算機視覺中基礎且富有挑戰性的問題——對於一張輸入圖像,我們通過生成二進位圖像來標記陰影區域,陰影區域的檢測為進一步獲取圖像中的光照情況、物體的形狀與位置,以及攝像機的參數提供了可能。與此同時,陰影的存在也為計算機視覺中進一步理解圖像的算法,例如物體的檢測與跟蹤,帶來了障礙。
  • Python並發編程初步
    另一個方面是採用並發方式執行,重複利用多核CPU優勢加速執行。關於並發編程大家可能比較熟悉的是Golang的協程、通道和Node.js 的async.parallel異步並發編程。就並發編程來說,Python不是一門合適的語言,主要是Python有一個解析器(CPython)內置的全局解釋鎖GIL。
  • Getmax 團隊:KDD CUP 2018 兩冠一亞團隊解題思路| AI 研習社第 55...
    原標題:Getmax 團隊:KDD CUP 2018 兩冠一亞團隊解題思路| AI 研習社第 55 期猿桌會 今年 KDD CUP 設立三項大獎,分別為 General Track、Last Ten-Day Prediction Track 以及 Second 24-Hour Prediction Track,從不同維度獎勵表現突出的團隊。
  • 北京城市氣象研究所範水勇:數值天氣預報介紹 | AI 研習社87期大...
    雷鋒網 AI分享主題:數值天氣預報介紹分享提綱:什麼是數值天氣預報「睿圖」數值天氣預報系統介紹「睿圖」預報數據怎麼做出來的雷鋒網 AI業內主要默認有三種基本的天氣預報模式:第一種是根據天氣學原理和經驗建立的,以物理定性關係為主的天氣學模式;第二種是由當前氣象要素與未來天氣之間的統計關係建立的統計學模式;第三種則是利用當前氣象要素的分布與未來天氣之間的物理定量關係建立的動力學模式。簡單進行總結的話,第一種模式對應的是天氣圖方法;第二種模式對應的是統計預報方法;第三種模式對應的是數值預報方法。
  • 11 個優秀的 Python 編譯器和解釋器
    網址:https://winpython.github.io4.Skulpt網站:https://www.activestate.com/products/activepython8. Nutika網站:https://www.activestate.com/products/activepython9. Jython
  • 語法研習社 | 「結構詞」與「意義詞」
    「太離語法研習社」是我的一個設想,目前還在規劃中。這個「研習社」只做一件事:專注英語技能培訓。我一直認為,學習外語這件事,成年人相比於小孩子優勢大得多,很多人學不好英語,無非是沒方法、沒毅力和沒時間這三個原因。「語法研習社」要做的,就是把英語學習的行之有效的方法分享給大家。這些方法,結合了我個人的學習經驗,還有很多經典的語法理論,是經得起推敲的。
  • | AI研習社62期大講堂
    在近日的 AI 研習社大講堂上,清華大學的王宇龍就從模型理解的角度入手,為我們詳細介紹了如何通過發現網絡中的關鍵數據通路(critical data routing paths, CDRPs),更好地理解網絡。
  • 葛笑雨:應用於智能體(Agent)的空間物理定性推理技術| AI 研習社第...
    近日,在雷鋒網 AI 研習社公開課上,澳大利亞國立大學葛笑雨博士就帶領大家認識定性物理推理並感受其中的樂趣。公開課回放視頻網址:http://www.mooc.ai/open/course/531葛笑雨:Dorabot 算法團隊負責人,澳大利亞國立大學博士,計算機科學系人工智慧專業,導師 是 Jochen Renz,主要研究方向為空間物理推理,研究成果在 IJCAI、AAAI、ECAI、KR 上發表過。
  • 「新零售·研習社」文具好貨分享第101期
    一起玩轉社群,就在文聚社。圖文分享者:靜心~佳佳文具來自:【新零售·研習社】12月14日分享者微信號:wtaijj大家好,我是來自河南縣城的一家小店,感謝小陸的邀請,提供這個和大家交流的機會,在群裡的這段時間,通過聊天學到了不少東西