標籤:統一 定義 src 怎樣 整數 async else 同步 rgs
1.用fork建立進程(Linux中使用)
1 import os2 #fork函數,只在Unix/Linux/Mac上運?,windows不可以3 pid = os.fork()4 if pid == 0:5 print(‘hello--1‘)6 else:7 print(‘hello--2‘)
程式走到os.fork()時,會建立出一個子進程,並將父進程中的所有資訊複製到子進程中,父進程和子進程都會從os.fork()中得到一個傳回值,子進程中這個傳回值是0,而父進程中這個傳回值就是子進程的id號
注意:fork被調用時會返回兩個值,一個是代表子進程的0,另一個是代表父進程的子進程id號
父進程、子進程的執行順序沒有規律,完全取決於系統的調度演算法
擷取進程id號: 擷取當前進程的進程id號: getpid() 擷取父進程的進程id號: getppid()
多進程對於全域變數的影響:
多進程中,每個進程所有的資料都擁有一份(包括全域變數),不受影響
主要是因為多進程的實質是每個進程在cpu的各個核心上輪流佔用,每一時刻在cpu的各個核心上都只有一個進程
2.用multiprocessing來建立多進程
1 from multiprocessing import * 2 import os 3 4 def run_process(num): 5 print("子進程%d--->%d 它的父進程--->%d"%(num,os.getpid(),os.getppid())) 6 7 def main(): 8 # 開始搞5個進程 9 for num in range(5):10 # Process中常用的的參數有 target 、 args 、 kwargs 、name 其中name意為給這個進程命一個別名,如果不寫name參數,則預設為name = Process-N N為一個遞增的整數11 p = Process(target=run_process,args=(num,))12 p.start()13 # p.join() join()的作用是等待子進程結束再往下走,通常用於進程間的同步14 # join(timeout) join()中可接受一個逾時參數,以確定它要等待多少秒的時間15 16 if __name__ == "__main__":17 main()其啟動並執行結果如下:
運行結果中子進程的編號並沒有遵從for迴圈中的0,1,2,3,4的順序是因為子進程的運行是沒有順序而言的,它取決於系統的調度演算法
3.通過Process的子類來建立進程
1 from multiprocessing import Process 2 import os 3 4 # 建立一個Process的子類 5 class process_children(Process): 6 def __init__(self, num): 7 # 這裡主要是因為Process類中也有__init__方法 8 # 如果不加不寫這句話就相當於重寫了__init__方法,然而這並不是我們想要的結果 9 # 這句話的作用就是將子類中接收到的參數再傳給Process父類10 Process.__init__(self)11 self.num = num12 13 # 這個run方法一定要定義,且必須寫成run ,因為這個函數中的代碼決定了建立的子進程會怎樣執行14 def run(self):15 print("%s ---> 當前進程id為%s ,父進程為%s"%(self.num, os.getpid(), os.getppid()))16 17 def main():18 while True:19 for num in range(5):20 # 如果我們用Process的子類來建立進程,直接將需要傳遞的參數傳遞給類就可以了21 p = process_children(num)22 p.start()23 # p.join()24 25 if __name__ == "__main__":26 main()
4.進程池(代碼在Ubuntu下測試)
1 from multiprocessing import Pool 2 import os 3 4 def func(num): 5 print("%d---> 當前進程為:%d,它的父進程為:%d"%(num, os.getpid(), os.getppid())) 6 7 #開啟一個進程池,池中最大的進程數為3 8 #最大進程數的意思是統一時刻在這個進程池中的最多的進程數量是3 9 #如果進程池中有進程結束,才會為等待的進程建立出新的進程10 po=Pool(3)11 12 def main():13 for i in range(0,10):14 # apply_async為非阻塞模式 apply為阻塞模式 15 po.apply_async(func, args=(i,))16 print("start")17 #close一定要放在join的前面 18 po.close()19 #join的作用是讓主進程等待子進程執行完畢20 po.join()21 print("finish")22 23 if __name__ == "__main__":24 main()運行結果:
要點:最後的close() 一定要寫在join() 的前面
5.進程間的通訊------隊列Queue 隊列:first in first out(FIFO)---------先入先出 棧: first in last out(FILO)----------先入後出
隊列的使用:q = Queue(num) num表示隊列的最大長度
寫入:q.put(value) , q.put_nowait() 讀取:q.get() , q.get_nowait()
判斷:q.full() , q.empty() , q.qsize()
q.get([block[timeout]])
1> 可以使用Queue在兩個進程間傳遞資料,一個進程Queue.put() ,另一個進程Queue.get() 2> 進程池中的處理序間通訊需要再匯入multiprocessing中的Manager : from multiprocessing impor Manager,Pool 且使用Queue時需要用Manager()中的Queue,否則會報錯----------> q = Manager().Queue()
python 多進程