多處理模組
from __future__ import print_function
import multiprocessing
def countdown(count):
while count > 0:
print("Count value", count)
count -= 1
return
if __name__ == "__main__":
p1 = multiprocessing.Process(target=countdown, args=(10,))
p1.start()
p2 = multiprocessing.Process(target=countdown, args=(20,))
p2.start()
p1.join()
p2.join()
這裡,每個函式都在一個新程序中執行。由於 Python VM 的新例項正在執行程式碼,因此沒有 GIL
,你可以在多個核心上執行並行操作。
Process.start
方法啟動這個新程序,並使用引數 args
執行 target
引數中傳遞的函式。Process.join
方法等待程序 p1
和 p2
的執行結束。
根據 python 的版本和執行程式碼的平臺形式,新程序的啟動方式不同,例如 :
- Windows 使用
spawn
來建立新程序。 - 對於 unix 系統和早於 3.3 的版本,使用
fork
建立流程。
請注意,此方法不考慮 fork 的 POSIX 使用,因此會導致意外行為,尤其是在與其他多處理庫互動時。 - 使用 unix 系統和 3.4+版本,你可以選擇在程式開始時使用
multiprocessing.set_start_method
啟動fork
,forkserver
或spawn
的新流程。forkserver
和spawn
方法比分叉慢,但避免一些意想不到的行為。
POSIX fork 用法 :
在多執行緒程式中的 fork 之後,子程序可以安全地只呼叫非同步訊號安全函式,直到它呼叫 execve 為止。
( 見 )
使用 fork,將為所有當前互斥鎖啟動一個具有完全相同狀態的新程序,但只會啟動 MainThread
。這是不安全的,因為它可能導致競爭條件,例如 :
- 如果你在
MainThread
中使用Lock
並將其傳遞給另一個執行緒,該執行緒可能會在某個時刻將其鎖定。如果fork
同時發生,則新程序將以鎖定鎖啟動,該鎖將永遠不會釋放,因為此新程序中不存在第二個執行緒。
實際上,這種行為不應該在純 python 中發生,因為 multiprocessing
正確處理它,但如果你正在與其他庫互動,這種行為可能會發生,導致你的系統崩潰(例如在 macOS 上有 numpy /加速)。