最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

初步解析Python下的多進程編程

 更新時間:2015年04月28日 14:55:10   作者:廖雪峰  
這篇文章主要介紹了初步解析Python下的多進程編程,使用多進程編程一直是Python編程當中的重點和難點,需要的朋友可以參考下

要讓Python程序?qū)崿F(xiàn)多進程(multiprocessing),我們先了解操作系統(tǒng)的相關知識。

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

子進程永遠返回0,而父進程返回子進程的ID。這樣做的理由是,一個父進程可以fork出很多子進程,所以,父進程要記下每個子進程的ID,而子進程只需要調(diào)用getppid()就可以拿到父進程的ID。

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

# multiprocessing.py
import os

print 'Process (%s) start...' % os.getpid()
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)

運行結(jié)果如下:

Process (876) start...
I (876) just created a child process (877).
I am child process (877) and my parent is 876.

由于Windows沒有fork調(diào)用,上面的代碼在Windows上無法運行。由于Mac系統(tǒng)是基于BSD(Unix的一種)內(nèi)核,所以,在Mac下運行是沒有問題的,推薦大家用Mac學Python!

有了fork調(diào)用,一個進程在接到新任務時就可以復制出一個子進程來處理新任務,常見的Apache服務器就是由父進程監(jiān)聽端口,每當有新的http請求時,就fork出子進程來處理新的http請求。
multiprocessing

如果你打算編寫多進程的服務程序,Unix/Linux無疑是正確的選擇。由于Windows沒有fork調(diào)用,難道在Windows上無法用Python編寫多進程的程序?

由于Python是跨平臺的,自然也應該提供一個跨平臺的多進程支持。multiprocessing模塊就是跨平臺版本的多進程模塊。

multiprocessing模塊提供了一個Process類來代表一個進程對象,下面的例子演示了啟動一個子進程并等待其結(jié)束:

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 'Process will start.'
  p.start()
  p.join()
  print '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()方法啟動,這樣創(chuàng)建進程比fork()還要簡單。

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()
  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的默認大小在我的電腦上是4,因此,最多同時執(zhí)行4個進程。這是Pool有意設計的限制,并不是操作系統(tǒng)的限制。如果改成:

p = Pool(5)

就可以同時跑5個進程。

由于Pool的默認大小是CPU的核數(shù),如果你不幸擁有8核CPU,你要提交至少9個子進程才能看到上面的等待效果。
進程間通信

Process之間肯定是需要通信的,操作系統(tǒng)提供了很多機制來實現(xiàn)進程間的通信。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):
  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:
    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é)果如下:

Put A to queue...
Get A from queue.
Put B to queue...
Get B from queue.
Put C to queue...
Get C from queue.

在Unix/Linux下,multiprocessing模塊封裝了fork()調(diào)用,使我們不需要關注fork()的細節(jié)。由于Windows沒有fork調(diào)用,因此,multiprocessing需要“模擬”出fork的效果,父進程所有Python對象都必須通過pickle序列化再傳到子進程去,所有,如果multiprocessing在Windows下調(diào)用失敗了,要先考慮是不是pickle失敗了。
小結(jié)

在Unix/Linux下,可以使用fork()調(diào)用實現(xiàn)多進程。

要實現(xiàn)跨平臺的多進程,可以使用multiprocessing模塊。

進程間通信是通過Queue、Pipes等實現(xiàn)的。

相關文章

  • Pycharm打開.py文件和項目的幾種實現(xiàn)方式

    Pycharm打開.py文件和項目的幾種實現(xiàn)方式

    這篇文章主要介紹了Pycharm打開.py文件和項目的幾種實現(xiàn)方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2025-04-04
  • Python PyQt5實戰(zhàn)項目之網(wǎng)速監(jiān)控器的實現(xiàn)

    Python PyQt5實戰(zhàn)項目之網(wǎng)速監(jiān)控器的實現(xiàn)

    PyQt5以一套Python模塊的形式來實現(xiàn)功能。它包含了超過620個類,600個方法和函數(shù)。它是一個多平臺的工具套件,它可以運行在所有的主流操作系統(tǒng)中,包含Unix,Windows和Mac OS。PyQt5采用雙重許可模式。開發(fā)者可以在GPL和社區(qū)授權之間選擇
    2021-11-11
  • python操作excel之xlwt與xlrd

    python操作excel之xlwt與xlrd

    這篇文章主要介紹了python使用xlwt與xlrd操作excel,需要的朋友可以參考下
    2022-12-12
  • Python運算符重載詳解及實例代碼

    Python運算符重載詳解及實例代碼

    這篇文章主要介紹了Python運算符重載詳解及實例代碼的相關資料,需要的朋友可以參考下
    2017-03-03
  • python中copy和deepcopy的使用區(qū)別

    python中copy和deepcopy的使用區(qū)別

    本文主要介紹了python中copy和deepcopy的使用區(qū)別,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2024-04-04
  • Python基于鏈接表實現(xiàn)無向圖最短路徑搜索

    Python基于鏈接表實現(xiàn)無向圖最短路徑搜索

    鏈接表的存儲相比較鄰接炬陣,使用起來更方便,對于空間的使用是剛好夠用原則,不會產(chǎn)生太多空間浪費。所以本文將以鏈接表方式實現(xiàn)無向圖最短路徑搜索,需要的可以參考一下
    2022-04-04
  • python 列表降維的實例講解

    python 列表降維的實例講解

    今天小編就為大家分享一篇python 列表降維的實例講解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-06-06
  • python之如何使用openpyxl設置單元格樣式

    python之如何使用openpyxl設置單元格樣式

    這篇文章主要介紹了python之如何使用openpyxl設置單元格樣式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • python 按鈕點擊關閉窗口的實現(xiàn)

    python 按鈕點擊關閉窗口的實現(xiàn)

    這篇文章主要介紹了python 按鈕點擊關閉窗口的實現(xiàn)方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-03-03
  • Python撲克牌21點游戲?qū)嵗a

    Python撲克牌21點游戲?qū)嵗a

    大家好,本篇文章主要講的是Python撲克牌21點游戲?qū)嵗a,感興趣的同學趕快來看一看吧,對你有幫助的話記得收藏一下,方便下次瀏覽
    2021-12-12

最新評論

英山县| 新泰市| 岗巴县| 左权县| 长子县| 和田市| 永州市| 西青区| 镇沅| 澎湖县| 晋江市| 徐水县| 永川市| 乌兰察布市| 广东省| 肃北| 诸暨市| 辰溪县| 静宁县| 抚远县| 江油市| 河津市| 肇州县| 全椒县| 新安县| 永胜县| 同江市| 敖汉旗| 化德县| 弥渡县| 淮南市| 耒阳市| 芦山县| 拜城县| 启东市| 资源县| 宣恩县| 灵川县| 湖南省| 龙泉市| 枝江市|