當前位置:
首頁 > 最新 > 深入Python多進程編程基礎

深入Python多進程編程基礎

多進程編程知識是Python程序員進階高級的必備知識點,我們平時習慣了使用multiprocessing庫來操縱多進程,但是並不知道它的具體實現原理。下面我對多進程的常用知識點都簡單列了一遍,使用原生的多進程方法調用,幫助讀者理解多進程的實現機制。代碼跑在linux環境下。沒有linux條件的,可以使用docker或者虛擬機運行進行體驗。


生成子進程

Python生成子進程使用,它將產生一個子進程。fork調用同時在父進程和主進程同時返回,在父進程中返回子進程的pid,在子進程中返回0,如果返回值小於零,說明子進程產生失敗,一般是因為操作系統資源不足。


我們調用方法多次就可以生成多個子進程,前提是必須保證是在父進程里執行,如果是子進程,就不要在調用了。

運行,輸出


使用time.sleep可以使進程休眠任意時間,單位為秒,可以是小數


使用os.kill(pid, sig_num)可以向進程號為pid的子進程發送信號,sig_num常用的有SIGKILL(暴力殺死,相當於kill -9),SIGTERM(通知對方退出,相當於kill不帶參數),SIGINT(相當於鍵盤的ctrl+c)。

運行,我們看到控制台輸出如下

說明os.kill執行之後,子進程已經停止輸出了


在上面的例子中,os.kill執行完之後,我們通過ps -ef|grep python快速觀察進程的狀態,可以發現子進程有一個奇怪的顯示

待父進程終止後,子進程也一塊消失了。那是什麼含義呢?

它的含義是「殭屍進程」。子進程結束後,會立即成為殭屍進程,殭屍進程佔用的操作系統資源並不會立即釋放,它就像一具屍體啥事也不幹,但是還是持續佔據著操作系統的資源(內存等)。


如果徹底幹掉殭屍進程?父進程需要調用waitpid(pid, options)函數,「收割」子進程,這樣子進程才可以灰飛煙滅。waitpid函數會返回子進程的退出狀態,它就像子進程留下的臨終遺言,必須等父進程聽到後才能徹底瞑目。

運行python kill.py輸出如下

我們看到waitpid返回了一個tuple,第一個是子進程的pid,第二個9是什麼含義呢,它在不同的操作系統上含義不盡相同,不過在Unix上,它通常的value是一個16位的整數值,前8位表示進程的退出狀態,後8位表示導致進程退出的信號的整數值。所以本例中退出狀態位0,信號編號位9,還記得這個命令么,就是這個9表示暴力殺死進程。

如果我們將os.kill換一個信號才看結果,比如換成os.kill(pid, signal.SIGTERM),可以看到返回結果變成了,15就是SIGTERM信號的整數值。

還可以起到等待子進程結束的功能,如果子進程不結束,那麼該調用會一直卡住。


SIGTERM信號默認處理動作就是退出進程,其實我們還可以設置SIGTERM信號的處理函數,使得它不退出。

我們在子進程里設置了信號處理函數,SIG_IGN表示忽略信號。我們發現第一次調用os.kill之後,子進程會繼續輸出。說明子進程沒有被殺死。第二次os.kill之後,子進程終於停止了輸出。

接下來我們換一個自定義信號處理函數,子進程收到SIGTERM之後,列印一句話再退出。

輸出如下

信號處理函數有兩個參數,第一個sig_num表示被捕獲信號的整數值,第二個frame不太好理解,一般也很少用。它表示被信號打斷時,Python的運行的棧幀對象信息。讀者可以不必深度理解。

下面我們使用多進程進行一個計算圓周率PI。對於圓周率PI有一個數學極限公式,我們將使用該公司來計算圓周率PI。

先使用單進程版本

輸出

這個程序跑了有一小會才出結果,不過這個值已經非常接近圓周率了。

接下來我們用多進程版本,我們用redis進行進程間通信。

我們將級數之和的計算拆分成10個子進程計算,每個子進程負責1/10的計算量,並將計算的中間結果扔到redis的隊列中,然後父進程等待所有子進程結束,再將隊列中的數據全部匯總起來計算最終結果。

輸出如下

這個結果和單進程結果一致,但是花費的時間要縮短了不少。

這裡我們之所以使用redis作為進程間通信方式,是因為進程間通信是一個比較複雜的技術,我們需要單獨一篇文章來仔細講,各位讀者請耐心聽我下回分解,我們將會使用進程間通信技術來替換掉這裡的redis。


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 Python 的精彩文章:

整理的最全 python常見面試題
Python商務辦公——python+pandas高效實現Excel文件合併與分析

TAG:Python |