1. 程式人生 > >python的os模組fork、wait、system、exec、popen、exit函式講解

python的os模組fork、wait、system、exec、popen、exit函式講解

雖然程序可在單獨的記憶體空間中執行,但除非這些Python程序在單獨的處理器上執行,否則,實際並不是“同時”執行的。是由作業系統把處理器的時間片分配給一個程序,用完時間片後就需退出處理器等待另一個時間片的到來。

另一種方式是在程式中指定多個“執行執行緒”,讓它們在相同的記憶體空間中工作。這稱為“多執行緒處理”。執行緒比程序更有效,因為作業系統不必為每個執行緒建立單獨的記憶體空間。新建程序用os.fork函式。但它只在POSIX系統上可用,在windows版的python中,os模組沒有定義os.fork函式。相反,windows程式設計師用多執行緒程式設計技術來完成併發任務。

os.fork函式建立程序的過程是這樣的。

程式每次執行時,作業系統都會建立一個新程序來執行程式指令。程序還可呼叫os.fork,要求作業系統新建一個程序。父程序是呼叫os.fork函式的程序。父程序所建立的程序叫子程序。

每個程序都有一個不重複的程序ID號。或稱pid,它對程序進行標識子程序與父程序完全相同,子程序從父程序繼承了多個值的拷貝。如全域性變數和環境變數。兩個程序的唯一區別是fork的返回值。子程序接收返回值0,而父程序接收子程序的pid作為返回值

用os.fork建立的子程序和父程序作為非同步的併發程序而單獨執行。非同步是指它們各行其是,相互間不進行同步;併發是指它們可同時執行。所以我們無法知道子程序和父程序的相對速度如沒有子程序,會引發OSError錯誤。

os.wait函式用於等待子程序結束(只適用於UNIX相容系統)。該函式返回包含兩個元素的元組,包括已完成的子程序號pid。以及子程序的退出狀態,返回狀態為0,表明子程序成功完成。返回狀態為正整數表明子程序終止時出錯。os.wait要求父程序等待它的任何一個子程序結束執行,然後喚醒父程序。

要指示父程序等候一個指定的子程序終止,可在父程序中使用os.waitpid函式(只適用於unix相容系統)。它可等候一個指定程序結束,然後返回一個雙元素元組,其中包括子程序的pid和子程序的退出狀態。函式呼叫將pid作為第一個引數傳遞。並將一個選項作為第二個選項,如果第一個引數大於0,則waitpid會等待該pid結束,如果第一個引數是-1,則會等候所有子程序,也就和os.wait一樣。

os.system 和 os.exec函式族來執行系統命令和其它程式。os.system使用shell來執行系統命令,然後在命令結束之後把控制權返回給原始程序;os.exec函式族在執行完命令後不將控制權返回給呼叫程序。它會接管Python程序,pid不變。這兩個函式支援unix和windows平臺。

os.popen()函式可執行命令,並獲得命令的stdout流。函式要取得兩個引數,一個是要執行的命令,另一個是呼叫函式所用的模式。如“r"只讀模式。os.popen2()函式執行命令,並獲得命令的stdout流和stdin流。函式返回一個元組,其中包含有兩個檔案物件,一個物件對應stdin流,一個物件對應stdout流。

程序使用IPC機制在程序間傳遞資訊,一種IPC機制是“管道”,它是一種類似於檔案的物件,提供單向通訊渠道。父程序可開啟一個管道,再分支一個子程序。父程序使用管道將資訊寫入(傳送到)子程序,而子程序使用管道從父程序讀取資訊。在python中使用os.pipe函式建立管道。

os._exit()類似於sys.exit(),但它不執行任何的清除工作(例如重新整理緩衝區)。所以os._exit()尤其適用於退出子程序。如果程式使用sys.exit(),作業系統會回收父程序或其它子程序可能仍然需要的資源。傳給os._exit()函式的引數必須是程序的退出狀態。退出狀態為0,表示正常終止。

程序也可用訊號進行通訊。所謂“訊號”,是作業系統採取非同步方式傳給程式的訊息。如CTRL+C會傳遞一個“中斷訊號”,通常該訊號導致程式中止。然而程式完全可以指定用不同的行動來響應任何一個訊號。在訊號處理中,程式要接收訊號,並根據那個訊號採取一項行動。

錯誤(例如向已關閉管道寫入)、事件(例如計時器變成0)以及使用者輸入(例如按ctrl+c)都會產生訊號。針對每個訊號,每個python程式都有一個預設的訊號處理程式,並不是所有作業系統。

都能從一個正在執行的程式建立單獨的程序,所以,程序管理是移植性最差的一項Python程序特性。每個系統都定義了特有訊號集。signal是依賴於具體平臺的模組,其中只包含系統定義的訊號。