Python多進程

Python多進程

Python中進程創(chuàng)建方式有兩種:

  1. fork:使用Python提供的os模塊。
pid = os.fork();
pid即為創(chuàng)建出的子進程

Python在創(chuàng)建進程時會返回兩次;一般方法只返回一次,Python分別在子進程、父進程中分別返回創(chuàng)建出的進程的ID。

Unix/Linux操作系統(tǒng)提供了一個fork()系統(tǒng)調(diào)用,它非常特殊。普通的函數(shù)調(diào)用,調(diào)用一次,返回一次,
但是fork()調(diào)用一次,返回兩次,因為操作系統(tǒng)自動把當前進程(稱為父進程)復(fù)制了一份(稱為子進程),
然后,分別在父進程和子進程內(nèi)返回。

子進程返回的ID一直為0

父進程返回的ID則是創(chuàng)建出的進程ID,父進程會保存該ID。

pid = os.fork();
if pid == 0:
    print('我是子進程我的編號是%1s,我的父進程的編號是%2s' % (os.getpid(), os.getppid()))
else:
    print('我是父進程我的編號是%1s,我剛剛創(chuàng)建了一個子進程,編號是%2s' % (os.getpid(), pid))

輸出結(jié)果:

我是子進程我的編號是12688,我的父進程的編號是12687
我是父進程我的編號是12687,我剛剛創(chuàng)建了一個子進程,編號是12688

2.使用multiprocessing模塊提供的Process、Pool 動態(tài)批量創(chuàng)建進程

為什么又要提出一個multiprocessing模塊創(chuàng)建進程,單單fork不就OK。

因為。。。因為windows不支持直接fork進程。<font color = red >(劃重點,這個要考)</font>而linux/Unix系列支持。(所以,人生苦短,使用mac學(xué)習Python)

使用Process創(chuàng)建也很簡單。

# 使用process對象進行創(chuàng)建進程

def run_proc(name):
    print('創(chuàng)建進程的名字為%s' % (name))


if __name__ == '__main__':
    print('-----------------------')
    print('創(chuàng)建子進程的父進程ID是%s' % (os.getpid()))
    #run_proc 是進程需要執(zhí)行的任務(wù)的方法名
    #args 是run_proc方法需要的參數(shù)
    p = Process(target=run_proc, args=('test',))
    p.start()
    p.join()
    print('執(zhí)行完了')

運行結(jié)果:

-----------------------
創(chuàng)建進程的名字為test
執(zhí)行完了

創(chuàng)建成功之后,直接<font color= red>p.start()</font>

<font color = red >p.join()</font>用作進程同步(線程中也要用到這個方法)。意為進程此時等待,直到子進程執(zhí)行完,再繼續(xù)執(zhí)行后續(xù)代碼。

這樣就實現(xiàn)了創(chuàng)建進程的代碼。很清晰,很清晰,很簡單。

接下來,就要進入高級的多進程創(chuàng)建了。

Pool

如果你有多進程的需求,就不要使用上述一個一個的創(chuàng)建了,

使用multiprocessing提供的Pool進程池進行多進程的創(chuàng)建。安全,文明,優(yōu)雅。

from multiprocessing import Pool
import os, time, random

def long_time_task(name):
    print('Run task %s (%s)...' % (name, os.getpid()))
    start = time.time()
    time.sleep(random.random() * 3)
    end = time.time()
    print('Task %s runs %0.2f seconds.' % (name, (end - start)))


if __name__ == '__main__':
    print('Parent process %s.' % os.getpid())
    p = Pool(2)
    for i in range(5):
        p.apply_async(long_time_task, args=(i,))
    print('Waiting for all subprocesses done...')
    # 必須要先進行close,然后才能進行join()
    p.close()
    p.join()
    print('All subprocesses done.')

執(zhí)行結(jié)果:


Parent process 12917.
Waiting for all subprocesses done...
Run task 0 (12920)...
Run task 1 (12921)...
Waiting for all subprocesses done...
Run task 0 (12922)...
Run task 1 (12923)...
Task 1 runs 0.29 seconds.
Run task 2 (12923)...
Task 1 runs 0.96 seconds.
Run task 2 (12921)...
Task 0 runs 1.01 seconds.
Run task 3 (12920)...
Task 2 runs 1.03 seconds.
Run task 4 (12921)...
Task 3 runs 1.17 seconds.
Task 0 runs 2.22 seconds.
Run task 3 (12922)...
Task 2 runs 2.13 seconds.
Run task 4 (12923)...
Task 4 runs 1.87 seconds.
All subprocesses done.

直接使用p = Pool(2)創(chuàng)建一個進程數(shù)為2的進程池。

p.apply_async(long_time_task, args=(i,))

將待執(zhí)行的任務(wù)與進程綁定<font color = red >apply_async</font>。

p.close():
對Pool對象調(diào)用join()方法會等待所有子進程執(zhí)行完畢,
調(diào)用join()之前必須先調(diào)用close(),
調(diào)用close()之后就不能繼續(xù)添加新的Process了。

項目源碼

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 一、進程的概念 相信很多同學(xué)都聽說過windows、linux,MacOS都是多任務(wù),多用戶的操作系統(tǒng)。那什么是多...
    轉(zhuǎn)身后的那一回眸閱讀 1,078評論 0 1
  • 1.多進程與多線程介紹 / 區(qū)別 現(xiàn)在,多核CPU已經(jīng)非常普及了,但是,即使過去的單核CPU,也可以執(zhí)行多任務(wù)。由...
    Wayne_Dream閱讀 754評論 1 4
  • 現(xiàn)在, 多核CPU已經(jīng)非常普及了, 但是, 即使過去的單核CPU, 也可以執(zhí)行多任務(wù)。 CPU執(zhí)行代碼都是順序執(zhí)行...
    LittlePy閱讀 4,920評論 0 3
  • 進程進程的概念是需要理解的,進程是操作系統(tǒng)中正在運行的一個程序?qū)嵗?,操作系統(tǒng)通過進程操作原語來對其進行調(diào)度。操作系...
    zhile_doing閱讀 546評論 0 0
  • 想讓python實現(xiàn)多進程(multiprocessing),我們要先區(qū)分不同的操作系統(tǒng)的不同之處。 Linux操...
    山有木兮有木兮閱讀 8,194評論 0 4

友情鏈接更多精彩內(nèi)容