版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
1、進程程序:例如xxx.py這是程序,是一個靜態(tài)的。進程:一個程序運行起來后,代碼+用到的資源 稱之為進程,它是操作系統(tǒng)分配資源的基本單元。不僅可以通過線程完成多任務(wù),進程也是可以的。進程的狀態(tài)工作中,任務(wù)數(shù)往往大于cpu的核數(shù),即一定有一些任務(wù)正在執(zhí)行,而另外一些任務(wù)在等待cpu進行執(zhí)行,因此導(dǎo)致了有了不同的狀態(tài)。就緒態(tài):運行的條件都已經(jīng)滿足,正在等在cpu執(zhí)行。執(zhí)行態(tài):cpu正在執(zhí)行其功能。等待態(tài):等待某些條件滿足,例如一個程序sleep了,此時就處于等待態(tài)。創(chuàng)建進程multiprocessing模塊就是跨平臺版本的多進程模塊,提供了一個Process類來代表一個進程對象,這個對象可以理解為
2、是一個獨立的進程,可以執(zhí)行另外的事情。示例:創(chuàng)建一個進程,執(zhí)行兩個死循環(huán)。from multiprocessing import Processimport timedef run_proc(): 子進程要執(zhí)行的代碼 while True: print(-2-) time.sleep(1)if _name_=_main_: p = Process(target=run_proc) p.start() while True: print(-1-) time.sleep(1)說明創(chuàng)建子進程時,只需要傳入一個執(zhí)行函數(shù)和函數(shù)的參數(shù),創(chuàng)建一個Process實例,用start()方法啟動方法說明Proce
3、ss( target , name , args , kwargs)target:如果傳遞了函數(shù)的引用,可以任務(wù)這個子進程就執(zhí)行這里的代碼args:給target指定的函數(shù)傳遞的參數(shù),以元組的方式傳遞kwargs:給target指定的函數(shù)傳遞命名參數(shù)name:給進程設(shè)定一個名字,可以不設(shè)定Process創(chuàng)建的實例對象的常用方法:start():啟動子進程實例(創(chuàng)建子進程)is_alive():判斷進程子進程是否還在活著join(timeout):是否等待子進程執(zhí)行結(jié)束,或等待多少秒terminate():不管任務(wù)是否完成,立即終止子進程Process創(chuàng)建的實例對象的常用屬性:name:當(dāng)前進程
4、的別名,默認為Process-N,N為從1開始遞增的整數(shù)pid:當(dāng)前進程的pid(進程號)示例:from multiprocessing import Processimport osfrom time import sleepdef run_proc(name, age, *kwargs): for i in range(10): print(子進程運行中,name= %s,age=%d ,pid=%d. % (name, age, os.getpid() print(kwargs) sleep(0.2)if _name_=_main_: p = Process(target=run_pro
5、c, args=(test,18), kwargs=m:20) p.start() sleep(1) # 1秒中之后,立即結(jié)束子進程 p.terminate() p.join()Pool開啟過多的進程并不能提高你的效率,反而會降低你的效率,假設(shè)有500個任務(wù),同時開啟500個進程,這500個進程除了不能一起執(zhí)行之外(cpu沒有那么多核),操作系統(tǒng)調(diào)度這500個進程,讓他們平均在4個或8個cpu上執(zhí)行,這會占用很大的空間。如果要啟動大量的子進程,可以用進程池的方式批量創(chuàng)建子進程:def task(n): print(-start.format(n) time.sleep(1) print(-en
6、d.format(n)if _name_ = _main_: p = Pool(8) # 創(chuàng)建進程池,并指定線程池的個數(shù),默認是CPU的核數(shù) for i in range(1, 11): # p.apply(task, args=(i,) # 同步執(zhí)行任務(wù),一個一個的執(zhí)行任務(wù),沒有并發(fā)效果 p.apply_async(task, args=(i,) # 異步執(zhí)行任務(wù),可以達到并發(fā)效果 p.close() p.join()進程池獲取任務(wù)的執(zhí)行結(jié)果:def task(n): print(-start.format(n) time.sleep(1) print(-end.format(n) retu
7、rn n * 2if _name_ = _main_: p = Pool(4) for i in range(1, 11): res = p.apply_async(task, args=(i,) # res 是任務(wù)的執(zhí)行結(jié)果 print(res.get() # 直接獲取結(jié)果的弊端是,多任務(wù)又變成同步的了 p.close() # p.join() 不需要再join了,因為 res.get()本身就是一個阻塞方法異步獲取線程的執(zhí)行結(jié)果:import timefrom multiprocessing.pool import Pooldef task(n): print(-start.format(
8、n) time.sleep(1) print(-end.format(n) return n * 2if _name_ = _main_: p = Pool(4) res_list = for i in range(1, 11): res = p.apply_async(task, args=(i,) res_list.append(res) # 使用列表來保存進程執(zhí)行結(jié)果 for re in res_list: print(re.get() p.close()進程間不能共享全局變量from multiprocessing import Processimport osnums = 11, 2
9、2def work1(): 子進程要執(zhí)行的代碼 print(in process1 pid=%d ,nums=%s % (os.getpid(), nums) for i in range(3): nums.append(i) print(in process1 pid=%d ,nums=%s % (os.getpid(), nums)def work2(): 子進程要執(zhí)行的代碼 nums.pop() print(in process2 pid=%d ,nums=%s % (os.getpid(), nums)if _name_ = _main_: p1 = Process(target=wo
10、rk1) p1.start() p1.join() p2 = Process(target=work2) p2.start() print(in process0 pid= ,nums=.format(os.getpid(),nums)運行結(jié)果:in process1 pid=2707 ,nums=11, 22in process1 pid=2707 ,nums=11, 22, 0in process1 pid=2707 ,nums=11, 22, 0, 1in process1 pid=2707 ,nums=11, 22, 0, 1, 2in process0 pid=2706 ,nums=
11、11, 22in process2 pid=2708 ,nums=11線程和進程功能進程,能夠完成多任務(wù),比如 在一臺電腦上能夠同時運行多個QQ。線程,能夠完成多任務(wù),比如 一個QQ中的多個聊天窗口。定義的不同進程是系統(tǒng)進行資源分配和調(diào)度的一個獨立單位.線程是進程的一個實體,是CPU調(diào)度和分派的基本單位,它是比進程更小的能獨立運行的基本單位.線程自己基本上不擁有系統(tǒng)資源,只擁有一點在運行中必不可少的資源(如程序計數(shù)器,一組寄存器和棧),但是它可與同屬一個進程的其他的線程共享進程所擁有的全部資源。區(qū)別一個程序至少有一個進程,一個進程至少有一個線程.線程的劃分尺度小于進程(資源比進程少),使得多線
12、程程序的并發(fā)性高。進程在執(zhí)行過程中擁有獨立的內(nèi)存單元,而多個線程共享內(nèi)存,從而極大地提高了程序的運行效率線線程不能夠獨立執(zhí)行,必須依存在進程中可以將進程理解為工廠中的一條流水線,而其中的線程就是這個流水線上的工人優(yōu)缺點線程和進程在使用上各有優(yōu)缺點:線程執(zhí)行開銷小,但不利于資源的管理和保護;而進程正相反。進程間通信-Queuefrom multiprocessing import Queueq=Queue(3) #初始化一個Queue對象,最多可接收三條put消息q.put(消息1) q.put(消息2)print(q.full() #Falseq.put(消息3)print(q.full()
13、#True#因為消息列隊已滿下面的try都會拋出異常,第一個try會等待2秒后再拋出異常,第二個Try會立刻拋出異常try: q.put(消息4,True,2)except: print(消息列隊已滿,現(xiàn)有消息數(shù)量:%s%q.qsize()try: q.put_nowait(消息4)except: print(消息列隊已滿,現(xiàn)有消息數(shù)量:%s%q.qsize()#推薦的方式,先判斷消息列隊是否已滿,再寫入if not q.full(): q.put_nowait(消息4)#讀取消息時,先判斷消息列隊是否為空,再讀取if not q.empty(): for i in range(q.qsize
14、(): print(q.get_nowait()說明初始化Queue()對象時(例如:q=Queue()),若括號中沒有指定最大可接收的消息數(shù)量,或數(shù)量為負值,那么就代表可接受的消息數(shù)量沒有上限(直到內(nèi)存的盡頭);Queue.qsize():返回當(dāng)前隊列包含的消息數(shù)量;Queue.empty():如果隊列為空,返回True,反之False ;Queue.full():如果隊列滿了,返回True,反之False;Queue.get(block, timeout):獲取隊列中的一條消息,然后將其從列隊中移除,block默認值為True;1)如果block使用默認值,且沒有設(shè)置timeout(單位秒
15、),消息列隊如果為空,此時程序?qū)⒈蛔枞ㄍT谧x取狀態(tài)),直到從消息列隊讀到消息為止,如果設(shè)置了timeout,則會等待timeout秒,若還沒讀取到任何消息,則拋出Queue.Empty異常;2)如果block值為False,消息列隊如果為空,則會立刻拋出Queue.Empty異常;Queue.get_nowait():相當(dāng)Queue.get(False);Queue.put(item,block, timeout):將item消息寫入隊列,block默認值為True;1)如果block使用默認值,且沒有設(shè)置timeout(單位秒),消息列隊如果已經(jīng)沒有空間可寫入,此時程序?qū)⒈蛔枞ㄍT趯懭霠?/p>
16、態(tài)),直到從消息列隊騰出空間為止,如果設(shè)置了timeout,則會等待timeout秒,若還沒空間,則拋出Queue.Full異常;2)如果block值為False,消息列隊如果沒有空間可寫入,則會立刻拋出Queue.Full異常;Queue.put_nowait(item):相當(dāng)Queue.put(item, False);使用Queue實現(xiàn)進程共享我們以Queue為例,在父進程中創(chuàng)建兩個子進程,一個往Queue里寫數(shù)據(jù),一個從Queue里讀數(shù)據(jù):from multiprocessing import Process, Queueimport os, time, random# 寫數(shù)據(jù)進程執(zhí)行
17、的代碼:def write(q): for value in A, B, C: print(Put %s to queue. % value) q.put(value) time.sleep(random.random()# 讀數(shù)據(jù)進程執(zhí)行的代碼:def read(q): while True: if not q.empty(): value = q.get(True) print(Get %s from queue. % value) time.sleep(random.random() else: breakif _name_=_main_: # 父進程創(chuàng)建Queue,并傳給各個子進程:
18、q = Queue() pw = Process(target=write, args=(q,) pr = Process(target=read, args=(q,) # 啟動子進程pw,寫入: pw.start() # 等待pw結(jié)束: pw.join() # 啟動子進程pr,讀取: pr.start() pr.join() print(所有數(shù)據(jù)都寫入并且讀完)進程池當(dāng)需要創(chuàng)建的子進程數(shù)量不多時,可以直接利用multiprocessing中的Process動態(tài)成生多個進程,但如果是上百甚至上千個目標(biāo),手動的去創(chuàng)建進程的工作量巨大,此時就可以用到multiprocessing模塊提供的Pool
19、方法。初始化Pool時,可以指定一個最大進程數(shù),當(dāng)有新的請求提交到Pool中時,如果池還沒有滿,那么就會創(chuàng)建一個新的進程用來執(zhí)行該請求;但如果池中的進程數(shù)已經(jīng)達到指定的最大值,那么該請求就會等待,直到池中有進程結(jié)束,才會用之前的進程來執(zhí)行新的任務(wù),請看下面的實例:from multiprocessing import Poolimport os, time, randomdef worker(msg): t_start = time.time() print(%s開始執(zhí)行,進程號為%d % (msg,os.getpid() # random.random()隨機生成01之間的浮點數(shù) time.
20、sleep(random.random()*2) t_stop = time.time() print(msg,執(zhí)行完畢,耗時%0.2f % (t_stop-t_start)po = Pool(3) # 定義一個進程池,最大進程數(shù)3for i in range(0,10): # Pool().apply_async(要調(diào)用的目標(biāo),(傳遞給目標(biāo)的參數(shù)元祖,) # 每次循環(huán)將會用空閑出來的子進程去調(diào)用目標(biāo) po.apply_async(worker,(i,)print(-start-)po.close() # 關(guān)閉進程池,關(guān)閉后po不再接收新的請求po.join() # 等待po中所有子進程執(zhí)行完
21、成,必須放在close語句之后print(-end-)運行效果:-start-0開始執(zhí)行,進程號為214661開始執(zhí)行,進程號為214682開始執(zhí)行,進程號為214670 執(zhí)行完畢,耗時1.013開始執(zhí)行,進程號為214662 執(zhí)行完畢,耗時1.244開始執(zhí)行,進程號為214673 執(zhí)行完畢,耗時0.565開始執(zhí)行,進程號為214661 執(zhí)行完畢,耗時1.686開始執(zhí)行,進程號為214684 執(zhí)行完畢,耗時0.677開始執(zhí)行,進程號為214675 執(zhí)行完畢,耗時0.838開始執(zhí)行,進程號為214666 執(zhí)行完畢,耗時0.759開始執(zhí)行,進程號為214687 執(zhí)行完畢,耗時1.038 執(zhí)行完畢,
22、耗時1.059 執(zhí)行完畢,耗時1.69-end-multiprocessing.Pool常用函數(shù)解析:apply_async(func, args, kwds) :使用非阻塞方式調(diào)用func(并行執(zhí)行,堵塞方式必須等待上一個進程退出才能執(zhí)行下一個進程),args為傳遞給func的參數(shù)列表,kwds為傳遞給func的關(guān)鍵字參數(shù)列表;close():關(guān)閉Pool,使其不再接受新的任務(wù);terminate():不管任務(wù)是否完成,立即終止;join():主進程阻塞,等待子進程的退出, 必須在close或terminate之后使用;進程池中的Queue如果要使用Pool創(chuàng)建進程,就需要使用multiprocessing.Manager()中的Queue(),而不是multiprocessing.Queue(),否則會得到一條如下的錯誤信息:RuntimeError: Queue objects should only be shared between processes through inheritance.下面的實例演示了進程池中的進程如何通信:# 修改import中的Queue為Managerfrom multiprocessing import Manager, Poolimport os, time, randomd
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 23《海底世界》說課稿-2024-2025學(xué)年三年級下冊語文統(tǒng)編版
- 專項工程造價咨詢修改合同:2024版一
- 2025版高端酒店窗簾制作與安裝合作協(xié)議3篇
- 6 將相和說課稿-2024-2025學(xué)年五年級上冊語文統(tǒng)編版
- 哈姆雷特悲劇情節(jié)讀后感
- 2024淘寶年度合作伙伴產(chǎn)品研發(fā)合同模板3篇
- 2024年股權(quán)收購與債務(wù)重組合同3篇
- 2024年長春婚姻解除合同樣本3篇
- 個人承包2024年度生產(chǎn)線能源管理合同3篇
- 2025年新能源汽車充電樁建設(shè)與運營管理合同模板3篇
- 環(huán)境因素控制措施
- 2024年下學(xué)期學(xué)校德育工作總結(jié)
- 公司員工出差車輛免責(zé)協(xié)議書
- 《電化學(xué)儲能系統(tǒng)艙大件運輸特殊要求》
- 2025年采購部工作計劃
- 2023年浙江杭州師范大學(xué)附屬醫(yī)院招聘聘用人員筆試真題
- 《防范于心反詐于行》中小學(xué)防范電信網(wǎng)絡(luò)詐騙知識宣傳課件
- 江蘇某小區(qū)園林施工組織設(shè)計方案
- 藥店醫(yī)保政策宣傳與執(zhí)行制度
- 體外膜肺氧合(ECMO)并發(fā)癥及護理
- 墊江縣中醫(yī)院2018年11月份臨床技能中心教學(xué)設(shè)備招標(biāo)項目招標(biāo)文件
評論
0/150
提交評論