1. 多進程與多線程 (1)背景:為何需要多進程或者多線程:在同一時間里,同一個電腦系統中如果允許兩個或者兩個以上的進程處於運行狀態,這便是多任務。多任務會帶來的好處例如用戶邊聽歌、邊上網、邊列印,而這些任務之間絲毫不會互相干擾。使用多進程技術,可大大提高電腦的運算速率。 (2)多進程與多線程的 ...
1. 多進程與多線程
(1)背景:為何需要多進程或者多線程:
在同一時間里,同一個電腦系統中如果允許兩個或者兩個以上的進程處於運行狀態,這便是多任務。多任務會帶來的好處例如用戶邊聽歌、邊上網、邊列印,而這些任務之間絲毫不會互相干擾。使用多進程技術,可大大提高電腦的運算速率。
(2)多進程與多線程的區別:
進程:程式在電腦上的一次執行活動。進程分為:系統進程和用戶進程。
當運行一個程式時,實際就是啟動了一個進程。程式是死的(靜態的),進程是活的(動態的)。
線程:是程式中的一個單一的順序控制流程。
進程是一個相互獨立的、可調度的執行單元,是系統獨立調度和分派CPU的基本單元(指運行中程式的調度單位)。
區別:進程是資源分配的最小單位,線程是CPU調度的最小單位。
線程是一個進程的實體,是由表示程式運行狀態的寄存器(如程式計數器、棧指針)以及堆棧組成,它是比進程更小的單位。
線程是程式中的一個執行流。一個執行流是由CPU運行程式代碼並操作程式的數據所形成的。因此,線程被認為是以CPU為主體的行為。
線程不包含進程地址空間中的代碼和數據,線程是計算過程在某一時刻的狀態。所以,系統在產生一個線程或各個線程之間切換時,負擔要比進程小得多。
線程是一個用戶級的實體,線程結構駐留在用戶空間中,能夠被普通的用戶級函數直接訪問。
一個線程本身不是程式,它必須運行於一個程式(進程)之中。因此,線程可以定義為一個程式中的單個執行流。
多線程是指一個程式中包含多個執行流,多線程是實現併發的一種有效手段。一個進程在其執行過程中,可以產生多個線程,形成多個執行流。每個執行流即每個線程也有它自身的產生、存在和消亡的過程。
多線程程式設計的含義就是可以將程式任務分成幾個並行的子任務。
在Windows系統中,進行CPU分配是以線程為單位的,一個進程可能由多個線程組成,這種情況更加複雜,有如下關係:
匯流排程數<=CPU數量,並行運行
匯流排程數>CPU數量,併發運行。 並行運行的效率明顯高於併發運行。
2. 多進程編程
- 進程的概念
第一,進程是一個實體,每一個進程都有它自己的地址空間,一般情況下,包括文本區域、數據區域和堆棧區域。
文本區域:存儲處理器執行的代碼;
數據區域:存儲變數和進程執行期間使用的動態分配的記憶體.
堆棧區域:存儲著活動過程中調用的指令和本地變數。
第二,進程是一個“執行中的程式”。程式是一個沒有生命的實體,只有處理器賦予程式生命時(操作系統執行之),它才能成為一個活動的實體,稱其為進程。
- 進程的特征
動態性:進程的實質是程式在多道程式系統中的一次執行過程,進程是動態產生、動態消亡的;
併發性:任何進程都可以同其他進程一起併發執行。
獨立性:進程是一個能夠獨立運行的基本單元,同時也是系統分配資源和調度的獨立單元;
非同步性:進程間的相互制約,使得進程具有執行的間斷性。
結構特征:進程由程式、數據、進程式控制制塊三部分組成。
多個不同進程可以包含相同的程式:一個程式在不同數據集里就構成不同的進程,能得到不同的結果,但是在執行過程中,程式不能發生變化。
- 進程的狀態:
就緒狀態:進程已經獲得除處理器外所需資源,等待分配處理器資源,只要分配了處理器進程就可執行;
運行狀態:進程占用處理器資源、處於此狀態的進程數目小於或者等於處理器的數目;阻塞狀態:由於進程等待某種條件,在條件滿足之前無法繼續執行。
- Miltiprocessing(多進程):
Multiprocessing是Python提供的非常好用的多進程包,用戶只需要簡單的定義一個函數,
Python就會自動地完成其他的所有事情。它支持子進程、進程間通信、數據共用、不同形式的同步,提供了包括Process、Queue、Pipe、Lock在內的各種組件。合理運用這些組件,可以輕鬆地完成單進程到併發執行的轉換。
創建進程Process模塊:
class multiprocessing.Process(group=None,target=None,name=None,args=(),kwargs={})
其中,group為None,它的存在是為了相容threading.Thread,target表示調用對象,name為別名,args表示調用對象的位置參數元組,kwargs表示調用對象的字典。
例如:創建函數並將其作為多個進程
import multiprocessing
import time
def worker_1(interval):
print("worker_1")
time.sleep(interval)
print("end worker_1")
def worker_2(interval):
print("worker_2")
time.sleep(interval)
print("end worker_2")
def worker_3(interval):
print("worker_3")
time.sleep(interval)
print("end worker_3")
if __name__=='__main__':
p1=multiprocessing.Process(target=worker_1,args=(2,))
p2=multiprocessing.Process(target=worker_2,args=(3,))
p3=multiprocessing.Process(target=worker_3,args=(4,))
p1.start()
p2.start()
p3.start()
print("The number of CPU is:"+str(multiprocessing.cpu_count()))
for p in multiprocessing.active_children():
print("child p.name:"+p.name+"\tp.id"+str(p.pid))
#運行結果:
The number of CPU is:4
child p.name:Process-2 p.id9804
child p.name:Process-1 p.id9172
child p.name:Process-3 p.id6608
註釋#:上述代碼中使用multiprocessing.cpu_count()函數查看當前電腦的CPU數量,並通過語句multiprocessing.active_children()和for()迴圈的結合使用,能夠清楚地查看當前活動的進程數。運行結果以worker_1、2、3的順序輸出,說明這三個進程間是併發執行的,所以每次開始時的輸出順序可能有所不同。
- 守護進程Daemon
- 進程間通信技術Queue通信和Pipe管道(用到之時再補充,不太懂--Python程式設計實用教程--楊連賀)