Python多進程編程

來源:互聯網
上載者:User

Python 實現線程式編程的一種簡單且有效模式。但是,這種方法的一個缺陷就是它並不總是能夠提高應用程式的速度,因為全域解譯器鎖(Global Interpreter Lock,GIL)將線程有效地限制到一個核中。如果需要使用電腦中的所有核,那麼通常都需通過 對 經常使用 fork 操作來實現,從而提高速度。處理進程組是件困難的事情,因為為了在進程之間進行通訊,需要對所有調用進行協調,這通常會使事情變得更複雜。

自 2.6 版本起,Python 包括了一個名為 “多進程(multiprocessing)” 的模組來協助處理進程。該進程模組的 API 與線程 API 的工作方式有些相似點,但是也存在一些需要特別注意的不同之處。主要區別之一就是進程擁有的一些微妙的底層行為,這是進階 API 永遠無法完全抽象出來的。


os.fork 簡介

進程和線程在並發性的工作原理方面存在一些明顯的差異。在進程執行 fork 時,作業系統將建立具有 ID 的新的子進程,複製父進程的狀態(記憶體、環境變數等)。首先,在我們實際使用進程模組之前,先看一下 Python 中的一個非常基本的 fork 操作。

#!/usr/bin/env python
"""fork example"""
import os

def main():
child_pid = os.fork()
if child_pid == 0:
print "Child Process: PID# %s" % os.getpid()
else:
print "Parent Process: PID# %s" % os.getpid()

if __name__ == "__main__":
main()

下面來看一下進程之間的系統變數傳遞。

#!/usr/bin/env python
"""A fork that demonstrates a copied environment"""

import os

def main():
os.environ['prefix']="zip"
print "prefix environmental variable set to: %s" % os.environ['prefix']
os.environ['prefix']="tar"
print "prefixenvironmental variable changed to: %s" % os.environ['prefix']
child_pid = os.fork()
if child_pid == 0:
print "Child Process: PID# %s" % os.getpid()
print "Child prefixenvironmental variable == %s" % os.environ['prefix']
else:
print "Parent Process: PID# %s" % os.getpid()
print "Parent prefix environmental variable == %s" % osenviron['prefix']

if __name__ == "__main__":
main()

下面給出了 fork 的輸出:

prefix environmental variable set to: zip
prefix environmental variable changed to: tar
Parent Process: PID# 52333
Parent prefix environmental variable == tar
Child Process: PID# 52334
Child prefix environmental variable == tar

在輸出中,可以看到 “修改後的” 環境變數 prefix 留在了子進程和父進程中。您可以通過在父進程中再次修改環境變數來進一步測試這個樣本,您將看到子進程現在是完全獨立的,它有了自己的生命。

注意,子進程模組也可用於 fork 進程,但是實現方式沒有多進程模組那麼複雜。

下面看一下多進程實用的例子

#!/usr/bin/env python
from multiprocessing import Process
import os
import time

def sleeper(name, seconds):
print 'starting child process with id: ', os.getpid()
print 'parent process:', os.getppid()
print 'sleeping for %s ' % seconds
time.sleep(seconds)
print "Done sleeping"

if __name__ == '__main__':
print "in parent process (id %s)" % os.getpid()
p = Process(target=sleeper, args=('bob', 5))
p.start()
print "in parent process after child process start"
print "parent process about to join child process"
p.join()
print "in parent process after child process join"
print "parent process exiting with id ", os.getpid()
print "The parent's parent process:", os.getppid()

輸出如下:

in parent process (id 5245)
in parent process after child process start
parent process about to join child process
starting child process with id: 5246
parent process: 5245
sleeping for 5
Done sleeping
in parent process after child process join
parent process exiting with id 5245
The parent's parent process: 5231

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.