并发编程之多进程编程(python版)
生活随笔
收集整理的這篇文章主要介紹了
并发编程之多进程编程(python版)
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
目錄
1 python多進程編程概述
2 需求和方案
背景:
需求:
解決思路:
需要解決的問題和方案:
3 完整代碼
1 python多進程編程概述
- python中的多線程無法利用多核優(yōu)勢,如果想要充分地使用多核CPU的資源,在python中大部分情況需要使用多進程。Python提供了multiprocessing。
- multiprocessing模塊用來開啟子進程,并在子進程中執(zhí)行我們定制的任務(比如函數(shù)),multiprocessing模塊的功能眾多:支持子進程、通信和共享數(shù)據(jù)、執(zhí)行不同形式的同步,提供了Process、Queue、Pipe、Lock等組件。
- 與線程不同,進程沒有任何共享狀態(tài),進程修改的數(shù)據(jù),改動僅限于該進程內。
2 需求和方案
背景:
在服務器某文件夾路徑內,會接收軟件端發(fā)來的數(shù)據(jù)包(如果接收還不完整,該文件夾名稱會以‘-downloading’為后綴),數(shù)據(jù)包是文件夾格式,里面有個和文件夾名稱同名的ZIP包。
算法需要對發(fā)來的數(shù)據(jù)包進行解壓縮,然后處理壓縮包內的數(shù)據(jù),待數(shù)據(jù)處理完后,這個文件夾及其內容會移動到另外一個地方歸檔。
需求:
服務器需要支持多并發(fā)。
解決思路:
考慮到python多線程雞肋,采用多進程實現(xiàn)。
需要解決的問題和方案:
- 如何避免同一個數(shù)據(jù)包被多個進程解析?
- 方案:使用隊列來構建生產者(主進程)消費者(子進程)模式。所有新生成的數(shù)據(jù)包,其文件夾名稱統(tǒng)一放入一個共享隊列中,所有進程從該隊列中取數(shù)據(jù)包名稱,該隊列自帶‘鎖’的功能。
- 主進程被殺死時,如何保證子進程同時退出,而不變?yōu)楣聝哼M程?
- 方案:構建‘進程組’形式 + 向進程組發(fā)送SIGKILL信號
- 參考:
https://blog.csdn.net/lucia555/article/details/105957928/
?- https://www.cnblogs.com/domestique/p/8241219.html
3 完整代碼
from multiprocessing import Process, Queue
import os
import time
import signalimport zipfile
import shutildef unzip_file(sample_key_pair):try:zip_name = sample_key_pair + '.zip'sampleraw_zip = os.path.join('./zip/'+ sample_key_pair, zip_name)with zipfile.ZipFile(sampleraw_zip) as z:z.extractall(path='./zip/'+ sample_key_pair, members=None, pwd=None)except Exception as e:print('Fail to unzip file: {}', e)def mv_dir(sample_key_pair):shutil.move('./zip/'+ sample_key_pair, './mv_zip')def gan_huo_de_jin_cheng(zip_Queue):print('子進程 pid 是 %s, group id is %s' % (os.getpid(), os.getppid()))while True:if not zip_Queue.empty():# 1 抽取一個壓縮包sample_key_pair = zip_Queue.get()print('子進程:',os.getpid(),'獲取壓縮包',sample_key_pair)# 2 解壓unzip_file(sample_key_pair)# 3 移動文件夾mv_dir(sample_key_pair)#一旦主進程被殺死,子進程也全部關閉。
def term(sig_num, addtion):print('term current pid is %s, group id is %s' % (os.getpid(), os.getppid()))os.killpg(os.getpgid(os.getpid()), signal.SIGKILL)if __name__== '__main__': #在測試多進程編程時,需要加這個,不然調試報錯。raw_data_root = './zip'signal.signal(signal.SIGTERM, term)print('主進程 pid 是 %s' % os.getpid())zip_Queue = Queue() #隊列不指定大小,就無限大使用空間,隊列使用內存的空間zip_list = [] #搞個zip_Queue同內容的復制品,因為Queue中內容無法遍歷和查詢。#創(chuàng)建子進程for i in range(3): t = Process(target=gan_huo_de_jin_cheng, args=(zip_Queue, ))t.daemon = Truet.start()#遍歷到新的壓縮包,就壓入隊列while True:time.sleep(1) #1秒檢索一次文件夾sample_raw_list = os.listdir(raw_data_root)if len(sample_raw_list) != 0:# 1 檢索文件夾內是否有 ‘完好’ 的壓縮包,且壓縮包名字和隊列中名字不一致。for sample_raw_dir in sample_raw_list:sample_key_pair = sample_raw_dir.split('/')[-1]if(sample_key_pair.endswith("-downloading")): #如果數(shù)據(jù)包還沒下載好,跳過continue# 如果隊列中沒有此zip包文件夾,就加入隊列if sample_key_pair not in zip_list: zip_Queue.put(sample_key_pair)zip_list.append(sample_key_pair)if len(zip_list) > 100:zip_list.pop(0)#刪除第1個。(當zip_list超過100個時,進一個就刪一個,防止zip_list越來越大。)
主要參考:
- python并發(fā)編程之多進程(實踐篇) - anne199534 - 博客園
- Python 3 并發(fā)編程多進程之隊列(推薦使用) - 魚皮弟 - 博客園
- python 并發(fā)編程 多進程 隊列 - minger_lcm - 博客園
- python多進程編程,如何讓主進程和子進程都退出_走走看看-CSDN博客_python主進程退出時子進程也退出
- 主進程被殺死時,如何保證子進程同時退出,而不變?yōu)楣聝哼M程 - shy車隊破風手 - 博客園
- pytorch使用出現(xiàn)"RuntimeError: An attempt has been made to start a new process before the..." 解決方法 - 灰信網(軟件開發(fā)博客聚合)
- put_nowait與get_nowait - 江湖乄夜雨 - 博客園
- Python|隊列Queue - yangyidba - 博客園
- Python 隊列(Queue)用法_大魔王的博客-CSDN博客_python queue
總結
以上是生活随笔為你收集整理的并发编程之多进程编程(python版)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 原创:为什么晋国能称霸上百年,第一个称霸
- 下一篇: 原创:新四军司令遇袭,非但不痛恨,还营救