python提供了一個跨平臺的多進(jìn)程支持——multiprocessing模塊,其包含Process類來代表一個進(jìn)程對象
1、Process語法結(jié)構(gòu):( 注: 傳參的時候一定使用關(guān)鍵字傳參 )
?
2、自定義進(jìn)程類:需要繼承Process類
? ? ? 自定義類的時候必須注意的事項:
? ? ? ? ? 第一,必須繼承Process類的構(gòu)造方法
? ? ? ? ? 第二,必須重寫Process類的run()方法
? ? ? ? ? 第三,不能用實例化對象直接調(diào)用run()方法,而是調(diào)用start()方法
? ? ? ? ? 第四,在進(jìn)程改變實例化對象的數(shù)據(jù)時,這個數(shù)據(jù)是被隔離的,即改變數(shù)據(jù)不成功
# 自定義進(jìn)程類 class ProcessClass(Process): g_num = 100 def __init__ (self, interval): # 這行代碼必須添加上 super(). __init__ () self.interval = interval self.result = " 初始化 " def run(self): global g_num g_num = 120 print ( " 子進(jìn)程{},開始執(zhí)行,父進(jìn)程為{} " .format(os.getpid(), os.getppid())) start = time.time() time.sleep( 2 ) stop = time.time() print ( " {}執(zhí)行結(jié)束,耗時{:0.2f}秒 " .format(os.getpid(), stop- start)) self.result = " 運行之后的結(jié)果 " if __name__ == " __main__ " : t_start = time.time() print ( " 當(dāng)前進(jìn)程{} " .format(os.getpid())) p = ProcessClass(2 ) p.start() p.join() t_stop = time.time() # 數(shù)據(jù)隔離 print ( " 子進(jìn)程 任務(wù) 運行結(jié)果: " , p.result) # -----> 初始化 數(shù)據(jù)未改變 print (ProcessClass.g_num) # ------>100 數(shù)據(jù)未改變 print ( " (%s)執(zhí)行結(jié)束,耗時%0.2f " % (os.getpid(), t_stop - t_start))
?
3、進(jìn)程間的通信
? ? ? ? ? 像之前改變數(shù)據(jù),就要使用到進(jìn)程間的通信,可以使用multiprocessing模塊的Queue類來實現(xiàn)進(jìn)程間的通信
? ? ? ? ? Queue的常用方法:
? ? ? ? ? ? ? ? qsize(): 返回當(dāng)前隊列包含的消息(數(shù)據(jù))數(shù)量
? ? ? ? ? ? ? ? empty():如果隊列為空,返回True,否則False
? ? ? ? ? ? ? ? full():如果隊列滿了,返回True,否則False
? ? ? ? ? ? ? ? get() 或者 put()分別時阻塞式獲取 或者 阻塞式存儲隊列的一條消息(數(shù)據(jù)),然后獲取 或者 添加這條消息,如果隊列為空 或者 隊列滿了,在運行的過程阻塞
? ? ? ? ? ? ? ? get_nowait() 或者 put_nowait()分別時非阻塞式獲取 或者 非阻塞式存儲隊列的一條消息(數(shù)據(jù)),然后移除 和 添加這條消息,如果隊列為空 或者 隊列滿了,會拋出相應(yīng)的異常
?實例如下:
# 自定義進(jìn)程類 class ProcessClass(Process): g_num = 100 def __init__ (self, interval, q): # 這行代碼必須添加上 super(). __init__ () self.interval = interval self.result = " 初始化 " # 初始化一個隊列實例化對象 self.q = q def run(self): global g_num g_num = 120 print ( " 子進(jìn)程{},開始執(zhí)行,父進(jìn)程為{} " .format(os.getpid(), os.getppid())) start = time.time() time.sleep(self.interval) stop = time.time() print ( " {}執(zhí)行結(jié)束,耗時{:0.2f}秒 " .format(os.getpid(), stop- start)) self.result = " 運行之后的結(jié)果 " # 將消息(數(shù)據(jù))添加到隊列中 self.q.put(g_num) self.q.put(self.result) def get_data(self): return self.result if __name__ == " __main__ " : # 初始化一個隊列實例化對象,參數(shù)為隊列的長度 queues = Queue(5 ) print ( " 當(dāng)前進(jìn)程{} " .format(os.getpid())) p = ProcessClass(2 , queues) t_start = time.time() p.start() p.join() t_stop = time.time() # 數(shù)據(jù)隔離 print ( " 子進(jìn)程 任務(wù) 運行結(jié)果: " , p.get_data()) # -----> 初始化 數(shù)據(jù)未改變 print (ProcessClass.g_num) # ------>100 數(shù)據(jù)未改變 print ( " 子進(jìn)程 任務(wù) 運行結(jié)果: " , queues.get()) # -----> 120 數(shù)據(jù)未改變 print ( " 子進(jìn)程 任務(wù) 運行結(jié)果: " , queues.get()) # -----> 運行之后的結(jié)果 數(shù)據(jù)未改變 print ( " (%s)執(zhí)行結(jié)束,耗時%0.2f " % (os.getpid(), t_stop - t_start))
?
4、進(jìn)程池:
? ? ? ? ? 如果進(jìn)程有成千上萬個,手動創(chuàng)建進(jìn)程的工作量巨大,這個時候應(yīng)該用到multiprocessing模塊中的Pool類
? ? ? ? ? 這個類下有幾個方法比較常用:
? ? ? ? ? apply_async(func[, args[, kwds]]) :使用非阻塞方式調(diào)用func(并行執(zhí)行 ,堵塞方式必須等待上一個進(jìn)程退出才能執(zhí)行下一個進(jìn)程),args為傳遞給 func的參數(shù)列表,kwds為傳遞給func的關(guān)鍵字參數(shù)列表;
? ?? ?????apply(func[, args[, kwds]]):使用阻塞方式調(diào)用func ? close():關(guān)閉Pool,使其不再接受新的任務(wù);?
? ? ? ?????terminate():不管任務(wù)是否完成,立即終止;
? ?? ?????join():主進(jìn)程阻塞,等待子進(jìn)程的退出,?必須在close或terminate之后使用
主要實例:
# 進(jìn)程池 def worker(msg): start = time.time() print ( " {}開始執(zhí)行,進(jìn)程號為{} " .format(msg, os.getpid())) # random.random()生成0~1之間的隨機數(shù) time.sleep(random.random()*3 ) # time.sleep(3) stop = time.time() print (msg, " 執(zhí)行完畢,耗時{:.2f} " .format(stop- start)) if __name__ == " __main__ " : # 定義一個進(jìn)程池,最大數(shù)為3 po = Pool(3 ) for i in range(10 ): # 非阻塞式操作Pool.apply_async(要調(diào)用的目標(biāo),(傳遞給目標(biāo)的參數(shù)元組,)) # 每次循環(huán)將會用空閑出來的子進(jìn)程去調(diào)用目標(biāo) po.apply_async(worker, (i, )) # 阻塞式操作 # po.apply(worker, (i, )) print ( " start " .center(24, " - " )) po.close() po.join() print ( " end " .center(24, " - " ))
?
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
