多進程

fork

Python的os模塊封裝了常見的系統(tǒng)調(diào)用横堡,其中就包括fork,可以在Python程序中輕松創(chuàng)建子進程:

import os

print('Process (%s) start...' % os.getpid())
# Only works on Unix/Linux/Mac:
pid = os.fork()
if pid == 0:
    print('I am child process (%s) and my parent is %s.' % (os.getpid(), os.getppid()))
else:
    print('I (%s) just created a child process (%s).' % (os.getpid(), pid))
執(zhí)行結(jié)果
Process (876) start...
I (876) just created a child process (877).
I am child process (877) and my parent is 876.
multiprocessing

由于Python是跨平臺的迁客,自然也應(yīng)該提供一個跨平臺的多進程支持遭笋。multiprocessing模塊就是跨平臺版本的多進程模塊聋庵。

from multiprocessing import Process
import os

# 子進程要執(zhí)行的代碼
def run_proc(name):
    print('Run child process %s (%s)...' % (name, os.getpid()))

if __name__=='__main__':
    print('Parent process %s.' % os.getpid())
    p = Process(target=run_proc, args=('test',))
    print('Child process will start.')
    p.start()
    p.join()
    print('Child process end.')

執(zhí)行結(jié)果
Parent process 928.
Process will start.
Run child process test (929)...
Process end.
創(chuàng)建子進程時饱苟,只需要傳入一個執(zhí)行函數(shù)和函數(shù)的參數(shù),創(chuàng)建一個Process實例编矾,用start()方法啟動
join()方法可以等待子進程結(jié)束后再繼續(xù)往下運行熟史,通常用于進程間的同步。
Pool

如果要啟動大量的子進程窄俏,可以用進程池的方式批量創(chuàng)建子進程:

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(4)
    for i in range(5):
        p.apply_async(long_time_task, args=(i,))
    print('Waiting for all subprocesses done...')
    p.close()
    p.join()
    print('All subprocesses done.')

執(zhí)行結(jié)果:
Parent process 669.
Waiting for all subprocesses done...
Run task 0 (671)...
Run task 1 (672)...
Run task 2 (673)...
Run task 3 (674)...
Task 2 runs 0.14 seconds.
Run task 4 (673)...
Task 1 runs 0.27 seconds.
Task 3 runs 0.86 seconds.
Task 0 runs 1.41 seconds.
Task 4 runs 1.91 seconds.
All subprocesses done.

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

請注意輸出的結(jié)果限寞,task 0,1仰坦,2履植,3是立刻執(zhí)行的,而task 4要等待前面某個task完成后才執(zhí)行悄晃,pool的默認(rèn)大小與cpu核心數(shù)量相同玫霎,這里為4,

子進程

很多時候,子進程并不是自身,而是一個外部進程鼠渺。我們創(chuàng)建了子進程后鸭巴,還需要控制子進程的輸入和輸出。subprocess模塊可以讓我們非常方便地啟動一個子進程拦盹,然后控制其輸入和輸出鹃祖。

import subprocess

print('$ nslookup www.python.org')
r = subprocess.call(['nslookup', 'www.python.org'])
print('Exit code:', r)
運行結(jié)果:

$ nslookup www.python.org
Server:        192.168.19.4
Address:    192.168.19.4#53

Non-authoritative answer:
www.python.org    canonical name = python.map.fastly.net.
Name:    python.map.fastly.net
Address: 199.27.79.223

Exit code: 0

如果子進程還需要輸入,則可以通過communicate()方法輸入:

import subprocess

print('$ nslookup')
p = subprocess.Popen(['nslookup'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
output, err = p.communicate(b'set q=mx\npython.org\nexit\n')
print(output.decode('utf-8'))
print('Exit code:', p.returncode)
上面的代碼相當(dāng)于在命令行執(zhí)行命令nslookup普舆,然后手動輸入:

set q=mx
python.org
exit

運行結(jié)果如下:

$ nslookup
Server:        192.168.19.4
Address:    192.168.19.4#53

Non-authoritative answer:
python.org    mail exchanger = 50 mail.python.org.

Authoritative answers can be found from:
mail.python.org    internet address = 82.94.164.166
mail.python.org    has AAAA address 2001:888:2000:d::a6

Exit code: 0

進程間通信

Python的multiprocessing模塊包裝了底層的機制恬口,提供了Queue、Pipes等多種方式來交換數(shù)據(jù)沼侣。我們以Queue為例祖能,在父進程中創(chuàng)建兩個子進程,一個往Queue里寫數(shù)據(jù)蛾洛,一個從Queue里讀數(shù)據(jù)

from multiprocessing import Process, Queue
import os, time, random

# 寫數(shù)據(jù)進程執(zhí)行的代碼:
def write(q):
    print('Process to write: %s' % os.getpid())
    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):
    print('Process to read: %s' % os.getpid())
    while True:
        value = q.get(True)
        print('Get %s from queue.' % value)

if __name__=='__main__':
    # 父進程創(chuàng)建Queue养铸,并傳給各個子進程:
    q = Queue()
    pw = Process(target=write, args=(q,))
    pr = Process(target=read, args=(q,))
    # 啟動子進程pw,寫入:
    pw.start()
    # 啟動子進程pr轧膘,讀取:
    pr.start()
    # 等待pw結(jié)束:
    pw.join()
    # pr進程里是死循環(huán)钞螟,無法等待其結(jié)束,只能強行終止:
    pr.terminate()

運行結(jié)果如下:
Process to write: 50563
Put A to queue...
Process to read: 50564
Get A from queue.
Put B to queue...
Get B from queue.
Put C to queue...
Get C from queue
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末谎碍,一起剝皮案震驚了整個濱河市鳞滨,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌蟆淀,老刑警劉巖拯啦,帶你破解...
    沈念sama閱讀 218,858評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異熔任,居然都是意外死亡褒链,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評論 3 395
  • 文/潘曉璐 我一進店門笋敞,熙熙樓的掌柜王于貴愁眉苦臉地迎上來碱蒙,“玉大人,你說我怎么就攤上這事夯巷∪停” “怎么了?”我有些...
    開封第一講書人閱讀 165,282評論 0 356
  • 文/不壞的土叔 我叫張陵趁餐,是天一觀的道長喷兼。 經(jīng)常有香客問我,道長后雷,這世上最難降的妖魔是什么季惯? 我笑而不...
    開封第一講書人閱讀 58,842評論 1 295
  • 正文 為了忘掉前任吠各,我火速辦了婚禮,結(jié)果婚禮上勉抓,老公的妹妹穿的比我還像新娘贾漏。我一直安慰自己,他們只是感情好藕筋,可當(dāng)我...
    茶點故事閱讀 67,857評論 6 392
  • 文/花漫 我一把揭開白布纵散。 她就那樣靜靜地躺著,像睡著了一般隐圾。 火紅的嫁衣襯著肌膚如雪伍掀。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,679評論 1 305
  • 那天暇藏,我揣著相機與錄音蜜笤,去河邊找鬼。 笑死盐碱,一個胖子當(dāng)著我的面吹牛把兔,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播甸各,決...
    沈念sama閱讀 40,406評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼垛贤,長吁一口氣:“原來是場噩夢啊……” “哼焰坪!你這毒婦竟也來了趣倾?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,311評論 0 276
  • 序言:老撾萬榮一對情侶失蹤某饰,失蹤者是張志新(化名)和其女友劉穎儒恋,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體黔漂,經(jīng)...
    沈念sama閱讀 45,767評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡诫尽,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了炬守。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片牧嫉。...
    茶點故事閱讀 40,090評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖减途,靈堂內(nèi)的尸體忽然破棺而出酣藻,到底是詐尸還是另有隱情,我是刑警寧澤鳍置,帶...
    沈念sama閱讀 35,785評論 5 346
  • 正文 年R本政府宣布辽剧,位于F島的核電站,受9級特大地震影響税产,放射性物質(zhì)發(fā)生泄漏怕轿。R本人自食惡果不足惜偷崩,卻給世界環(huán)境...
    茶點故事閱讀 41,420評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望撞羽。 院中可真熱鬧阐斜,春花似錦、人聲如沸诀紊。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽渡紫。三九已至到推,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間惕澎,已是汗流浹背莉测。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評論 1 271
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留唧喉,地道東北人捣卤。 一個月前我還...
    沈念sama閱讀 48,298評論 3 372
  • 正文 我出身青樓,卻偏偏與公主長得像八孝,于是被迫代替她去往敵國和親董朝。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,033評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 本文是筆者學(xué)習(xí)廖雪峰Python3教程的筆記,在此感謝廖老師的教程讓我們這些初學(xué)者能夠一步一步的進行下去.如果讀者...
    相關(guān)函數(shù)閱讀 5,527評論 1 8
  • Python的os模塊封裝了常見的系統(tǒng)調(diào)用干跛,其中就包括fork子姜,可以在Python程序中輕松創(chuàng)建子進程: impo...
    牛崽兒酷閱讀 288評論 0 0
  • 一、進程的概念 相信很多同學(xué)都聽說過windows楼入、linux哥捕,MacOS都是多任務(wù),多用戶的操作系統(tǒng)嘉熊。那什么是多...
    轉(zhuǎn)身后的那一回眸閱讀 990評論 0 1
  • fork(Unix/Linux/Mac) Unix/Linux操作系統(tǒng)提供了一個fork()系統(tǒng)調(diào)用遥赚,它非常特殊。...
    LeeRich閱讀 452評論 0 0
  • 現(xiàn)在阐肤, 多核CPU已經(jīng)非常普及了凫佛, 但是, 即使過去的單核CPU孕惜, 也可以執(zhí)行多任務(wù)愧薛。 CPU執(zhí)行代碼都是順序執(zhí)行...
    LittlePy閱讀 4,795評論 0 3