1. 程式人生 > >Python 多程序 fork()詳解

Python 多程序 fork()詳解

程序

程序是程式的一次動態執行過程,它對應了從程式碼載入、執行到執行完畢的一個完整過程。程序是系統進行資源分配和排程的一個獨立單位。程序是由程式碼(堆疊段)、資料(資料段)、核心狀態和一組暫存器組成。
在多工作業系統中,通過執行多個程序來併發地執行多個任務。由於每個執行緒都是一個能獨立執行自身指令的不同控制流,因此一個包含多個執行緒的程序也能夠實現程序內多工的併發執行。
程序是一個核心級的實體,程序結構的所有成分都在核心空間中,一個使用者程式不能直接訪問這些資料。
程序的狀態:
建立、準備、執行、阻塞、結束。

程序間的通訊方式可以有:

  • 檔案
  • 管道
  • socket
  • 訊號
  • 訊號量
  • 共享記憶體

要讓Python程式實現多程序(multiprocessing),必須先了解作業系統的相關知識。
在Unix/Linux作業系統提供了一個fork()函式,它非常特殊,呼叫一次,返回兩次,因為作業系統將當前的程序(父程序)複製了一份(子程序),然後分別在父程序和子程序內返回。

Python中的程序

  • os.fork()
  • subprocess
  • processing
  • multiprocessing

fork()函式

函式原型:

Help on built-in function fork in module posix:

fork(...)
    fork() -> pid

    Fork a child process.
    Return 0
to child process and PID of child to parent process.

從fork()函式原型來看,它也屬於一個內建函式。
子程序永遠返回0,而父程序返回子程序的ID。這樣做的理由是,一個父程序可以fork()出很多子程序,所以,父程序要記下每個子程序的ID,而子程序只需要呼叫getppid()就可以拿到父程序的ID。

Python的程序函式fork()是在os模組,下面是一個關於程序的例子:

import os
print 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)

執行結果:

1526
I (1526) just created a child process (1527).
I am child process (1527) and my parent is 1526.

有了fork呼叫,一個程序在接到新的任務時,就可以複製出一個子程序來處理新任務。常見的Apache伺服器就是由父程序監聽埠,一旦有新的http請求時,就fork出子程序來處理新的http請求。
再看一個例子:

#coding=utf-8
import os
os.fork()
print 1

執行結果:

1
1

程式中,父程序中建立了一個子程序,子程序執行列印了一個1,回到父程序又列印了一個1,所以結果是列印了2個1。

需要注意的是,上面建立程序的函式都是Unix/Linux下的,Windows下是沒有的,那在Windows下又使用什麼實現多程序呢?
由於Python是跨平臺的,自然也應該提供一個跨平臺的多程序支援。multiprocessing模組就是跨平臺版本的多程序模組, 支援子程序、通訊和共享資料、執行不同形式的同步。
multiprocessing模組提供了一個Process類來建立一個新的程序物件。