一、簡介
我們將一個正在運行的程序稱為進程。每個進程都有它自己的系統狀態,包含內存狀態、打開文件列表、追蹤指令執行情況的程序指針以及一個保存局部變量的調用棧。通常情況下,一個進程依照一個單序列控制流順序執行,這個控制流被稱為該進程的主線程。在任何給定的時刻,一個程序只做一件事情。
一個程序可以通過Python庫函數中的os或subprocess模塊創建新進程(例如os.fork()或是subprocess.Popen())。然而,這些被稱為子進程的進程卻是獨立運行的,它們有各自獨立的系統狀態以及主線程。因為進程之間是相互獨立的,因此它們同原有的進程并發執行。這是指原進程可以在創建子進程后去執行其它工作。
雖然進程之間是相互獨立的,但是它們能夠通過名為進程間通信(IPC)的機制進行相互通信。一個典型的模式是基于消息傳遞,可以將其簡單地理解為一個純字節的緩沖區,而send()或recv()操作原語可以通過諸如管道(pipe)或是網絡套接字(network socket)等I/O通道傳輸或接收消息。還有一些IPC模式可以通過內存映射(memory-mapped)機制完成(例如mmap模塊),通過內存映射,進程可以在內存中創建共享區域,而對這些區域的修改對所有的進程可見。
多進程能夠被用于需要同時執行多個任務的場景,由不同的進程負責任務的不同部分。然而,另一種將工作細分到任務的方法是使用線程。同進程類似,線程也有其自己的控制流以及執行棧,但線程在創建它的進程之內運行,分享其父進程的所有數據和系統資源。當應用需要完成并發任務的時候線程是很有用的,但是潛在的問題是任務間必須分享大量的系統狀態。
當使用多進程或多線程時,操作系統負責調度。這是通過給每個進程(或線程)一個很小的時間片并且在所有活動任務之間快速循環切換來實現的,這個過程將CPU時間分割為小片段分給各個任務。例如,如果你的系統中有10個活躍的進程正在執行,操作系統將會適當的將十分之一的CPU時間分配給每個進程并且循環地在十個進程之間切換。當系統不止有一個CPU核時,操作系統能夠將進程調度到不同的CPU核上,保持系統負載平均以實現并行執行。
利用并發執行機制寫的程序需要考慮一些復雜的問題。復雜性的主要來源是關于同步和共享數據的問題。通常情況下,多個任務同時試圖更新同一個數據結構會造成臟數據和程序狀態不一致的問題(正式的說法是資源競爭的問題)。為了解決這個問題,需要使用互斥鎖或是其他相似的同步原語來標識并保護程序中的關鍵部分。舉個例子,如果多個不同的線程正在試圖同時向同一個文件寫入數據,那么你需要一個互斥鎖使這些寫操作依次執行,當一個線程在寫入時,其他線程必須等待直到當前線程釋放這個資源。
新聞熱點
疑難解答