python使用多進(jìn)程的實(shí)例詳解
python多線程適合IO密集型場景,而在CPU密集型場景,并不能充分利用多核CPU,而協(xié)程本質(zhì)基于線程,同樣不能充分發(fā)揮多核的優(yōu)勢。
針對計(jì)算密集型場景需要使用多進(jìn)程,python的multiprocessing與threading模塊非常相似,支持用進(jìn)程池的方式批量創(chuàng)建子進(jìn)程。
•創(chuàng)建單個(gè)Process進(jìn)程(使用func)
只需要實(shí)例化Process類,傳遞函數(shù)給target參數(shù),這點(diǎn)和threading模塊非常的類似,args為函數(shù)的參數(shù)
import os
from multiprocessing import Process
# 子進(jìn)程要執(zhí)行的代碼
def task(name):
print('run child process %s (%s)...' % (name, os.getpid()))
if __name__ == '__main__':
print('parent process %s.' % os.getpid())
p = Process(target=task, args=('test',))
p.start()
p.join()
print('process end.')
•創(chuàng)建單個(gè)Process進(jìn)程(使用class)
繼承Process類,重寫run方法創(chuàng)建進(jìn)程,這點(diǎn)和threading模塊基本一樣
import multiprocessing
import os
from multiprocessing import current_process
class Worker(multiprocessing.Process):
def run(self):
name = current_process().name # 獲取當(dāng)前進(jìn)程的名稱
print('run child process <%s> (%s)' % (name, os.getpid()))
print('In %s' % self.name)
return
if __name__ == '__main__':
print('parent process %s.' % os.getpid())
p = Worker()
p.start()
p.join()
print('process end.')
* 停止進(jìn)程
terminate()結(jié)束子進(jìn)程,但是會導(dǎo)致子進(jìn)程的資源無法釋放掉,是不推薦的做法,因?yàn)榻Y(jié)束的時(shí)候不清楚子線程的運(yùn)行狀況,有很大可能性導(dǎo)致子線程在不恰當(dāng)?shù)臅r(shí)刻被結(jié)束。
import multiprocessing
import time
def worker():
print('starting worker')
time.sleep(0.1)
print('finished worker')
if __name__ == '__main__':
p = multiprocessing.Process(target=worker)
print('執(zhí)行前:', p.is_alive())
p.start()
print('執(zhí)行中:', p.is_alive())
p.terminate() # 發(fā)送停止號
print('停止:', p.is_alive())
p.join()
print('等待完成:', p.is_alive())
•直接創(chuàng)建多個(gè)Process進(jìn)程
import multiprocessing
def worker(num):
print(f'Worker:%s %s', num)
return
if __name__ == '__main__':
jobs = []
for i in range(5):
p = multiprocessing.Process(target=worker, args=(i,))
jobs.append(p)
p.start()
•使用進(jìn)程池創(chuàng)建多個(gè)進(jìn)程
在利用Python進(jìn)行系統(tǒng)管理的時(shí)候,特別是同時(shí)操作多個(gè)文件目錄,或者遠(yuǎn)程控制多臺主機(jī),并行操作可以節(jié)約大量的時(shí)間。當(dāng)被操作對象數(shù)目不大時(shí),可以直接利用multiprocessing中的Process動態(tài)成生多個(gè)進(jìn)程,十幾個(gè)還好,但如果是上百個(gè),上千個(gè)目標(biāo),手動的去限制進(jìn)程數(shù)量卻又太過繁瑣,此時(shí)可以發(fā)揮進(jìn)程池的功效。
Pool可以提供指定數(shù)量的進(jìn)程供用戶調(diào)用,當(dāng)有新的請求提交到pool中時(shí),如果池還沒有滿,那么就會創(chuàng)建一個(gè)新的進(jìn)程用來執(zhí)行該請求;但如果池中的進(jìn)程數(shù)已經(jīng)達(dá)到規(guī)定最大值,那么該請求就會等待,直到池中有進(jìn)程結(jié)束,才會創(chuàng)建新的進(jìn)程來它。
import os
import random
import time
from multiprocessing import Pool
from time import ctime
def task(name):
print('start task %s (%s)...' % (name, os.getpid()))
start = time.time()
time.sleep(random.random() * 3)
print('end task %s runs %0.2f seconds.' % (name, (time.time() - start)))
if __name__ == '__main__':
print('parent process %s.' % os.getpid())
p = Pool() # 初始化進(jìn)程池
for i in range(5):
p.apply_async(task, args=(i,)) # 追加任務(wù) apply_async 是異步非阻塞的,就是不用等待當(dāng)前進(jìn)程執(zhí)行完畢,隨時(shí)根據(jù)系統(tǒng)調(diào)度來進(jìn)行進(jìn)程切換。
p.close()
p.join() # 等待所有結(jié)果執(zhí)行完畢,會等待所有子進(jìn)程執(zhí)行完畢,調(diào)用join()之前必須先調(diào)用close()
print(f'all done at: {ctime()}')
如果關(guān)心每個(gè)進(jìn)程的執(zhí)行結(jié)果,可以使用返回結(jié)果的get方法獲取,代碼如下
import os
import random
import time
from multiprocessing import Pool, current_process
from time import ctime
def task(name):
print('start task %s (%s)...' % (name, os.getpid()))
start = time.time()
time.sleep(random.random() * 3)
print('end task %s runs %0.2f seconds.' % (name, (time.time() - start)))
return current_process().name + 'done'
if __name__ == '__main__':
print('parent process %s.' % os.getpid())
result = []
p = Pool() # 初始化進(jìn)程池
for i in range(5):
result.append(p.apply_async(task, args=(i,))) # 追加任務(wù) apply_async 是異步非阻塞的,就是不用等待當(dāng)前進(jìn)程執(zhí)行完畢,隨時(shí)根據(jù)系統(tǒng)調(diào)度來進(jìn)行進(jìn)程切換。
p.close()
p.join() # 等待所有結(jié)果執(zhí)行完畢
for res in result:
print(res.get()) # get()函數(shù)得出每個(gè)返回結(jié)果的值
print(f'all done at: {ctime()}')
總結(jié)
以上所述是小編給大家介紹的python使用多進(jìn)程的實(shí)現(xiàn)代碼,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時(shí)回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
相關(guān)文章
解決新版Pycharm中Matplotlib圖像不在彈出獨(dú)立的顯示窗口問題
今天小編就為大家分享一篇解決新版Pycharm中Matplotlib圖像不在彈出獨(dú)立的顯示窗口問題,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-01-01
Python實(shí)現(xiàn)矩陣轉(zhuǎn)置的方法分析
這篇文章主要介紹了Python實(shí)現(xiàn)矩陣轉(zhuǎn)置的方法,結(jié)合實(shí)例形式較為詳細(xì)的分析了Python實(shí)現(xiàn)矩陣轉(zhuǎn)置的相關(guān)操作技巧,需要的朋友可以參考下2017-11-11
Python一行代碼實(shí)現(xiàn)自動發(fā)郵件功能
最近在自己學(xué)習(xí)Python爬蟲,學(xué)到了用Python發(fā)送郵件,覺得這個(gè)可能以后比較實(shí)用。所以這篇文章主要給大家介紹了如何通過Python一行代碼實(shí)現(xiàn)自動發(fā)郵件功能的相關(guān)資料,需要的朋友可以參考下2021-05-05
Python實(shí)現(xiàn)自動化郵件發(fā)送過程詳解
這篇文章主要介紹了如何利用Python實(shí)現(xiàn)自動化郵件發(fā)送,可以讓你擺脫繁瑣的重復(fù)性業(yè)務(wù),可以節(jié)省非常多的時(shí)間。感興趣的小伙伴可以試一試2022-01-01
詳解如何修改jupyter notebook的默認(rèn)目錄和默認(rèn)瀏覽器
這篇文章主要介紹了詳解如何修改jupyter notebook的默認(rèn)目錄和默認(rèn)瀏覽器,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01

