“線程是并發(fā)還是并行?進程又是并發(fā)還是并行?”面試官這問題一出口,我腦子里先是一片空白,然后開始快速檢索我那臺老舊大腦里的緩存——到底誰是并發(fā),誰是并行?
作為一個寫 Python 的程序員,我平時寫多線程的機會說多也不多,說少吧也不算少,但真讓我嘴上整出個定義,還真容易一臉懵。
所以,這篇就當給自己和大家補個課,也算是個“面試保命指南”。
并發(fā)和并行,到底啥區(qū)別?
先別急著答問題,我們得先整明白“并發(fā)”和“并行”到底是個啥。
? 并發(fā)(Concurrency):多個任務在“同一個時間段”交替執(zhí)行,看起來像同時發(fā)生,但其實是你一下、我一下,大家輪流干活。比如單核 CPU 模擬多線程運行,就是通過任務切換來實現(xiàn)的。
? 并行(Parallelism):多個任務在“同一時刻”真的同時執(zhí)行。比如多核 CPU 上一個線程一個核,大家一起跑步,不用輪流。
用個比喻:你一個人炒三個菜,這叫并發(fā);你找倆室友一人炒一個,這叫并行。
那線程和進程呢?是并發(fā)還是并行?
這問題本身其實是個陷阱,因為“線程”和“進程”是實現(xiàn)單位,不是“方式”。他們可以是并發(fā),也可以是并行,關鍵在于你的操作系統(tǒng)和硬件怎么安排。
但我們以 Python 的角度來看,事情就復雜了一點:
Python 中的線程:通常是并發(fā)
原因:GIL(全局解釋器鎖)

上面這個程序跑起來,你會發(fā)現(xiàn)就算你電腦有 8 核,也還是用不到幾個核。因為 GIL 存在于 CPython(Python 最主流的實現(xiàn))中,限制了同一時刻只能有一個線程在執(zhí)行 Python 字節(jié)碼。
所以多線程在 Python 中,CPU 密集型任務是并發(fā)(輪流跑),但不是并行。
不過,如果你是搞 IO 密集型的事(比如網(wǎng)絡請求、讀寫文件),Python 的線程還是挺香的,因為線程會在等待 IO 的時候切出去,讓其他線程繼續(xù)跑,這就很高效。
Python 中的進程:可以并行
用 multiprocessing 模塊就能創(chuàng)建多個子進程,每個進程有自己獨立的內(nèi)存空間和 GIL,所以可以真正實現(xiàn)并行。

這時候你的 CPU 就是真的雙核齊飛了,能感受到明顯的加速。
面試中怎么答更靠譜?
面試官一問你線程并發(fā)還是并行,你要先反問一句:“您是指 Python 中的嗎?”
然后根據(jù)情況出招:
? 如果是 Python 的線程:并發(fā)(主要受 GIL 限制)
? 如果是 Python 的進程:并行(多核執(zhí)行,互不干擾)
? 補充一句:如果是其他語言(比如 Java、C++)的線程,那線程也可能實現(xiàn)并行,因為它們沒有 GIL。
順便丟一句“IO 密集型任務用線程,CPU 密集型任務用進程”,再加點示例代碼,完事收工。
日常開發(fā)咋選?線程還是進程?
我自己覺得還是得看場景:
? 爬蟲、文件下載、數(shù)據(jù)庫操作:線程更輕便,適合用 threading 或 concurrent.futures.ThreadPoolExecutor
? 大規(guī)模數(shù)據(jù)計算、圖像處理、模型訓練:果斷用 multiprocessing,或者更高級的并行框架,比如 joblib, dask 等
當然,寫了這么多,不如現(xiàn)場背一段“金句”,比如:
“在 Python 中,由于 GIL 的限制,線程多用于 IO 密集型任務,而進程更適合 CPU 密集型任務,實現(xiàn)真正的并行計算。”
你這一說,八成面試官也懵了,咱算是扳回一局。
下次再有人問我線程并發(fā)還是并行,我可得先笑一下,再扔一段代碼,讓他看看咱也是刷過面經(jīng)的“資深調(diào)度器”。
以上就是“python面試題:線程是并發(fā)還是并行,進程是并發(fā)還是并行?”的詳細內(nèi)容,想要了解更多Python教程歡迎持續(xù)關注編程學習網(wǎng)。
掃碼二維碼 獲取免費視頻學習資料
- 本文固定鏈接: http://www.wangchenghua.com/post/13484/
- 轉載請注明:轉載必須在正文中標注并保留原文鏈接
- 掃碼: 掃上方二維碼獲取免費視頻資料
查 看2022高級編程視頻教程免費獲取