python的os模組fork、wait、system、exec、popen、exit函式講解
另一種方式是在程式中指定多個“執行執行緒”,讓它們在相同的記憶體空間中工作。這稱為“多執行緒處理”。執行緒比程序更有效,因為作業系統不必為每個執行緒建立單獨的記憶體空間。新建程序用os.fork函式。但它只在POSIX系統上可用,在windows版的python中,os模組沒有定義os.fork函式。相反,windows程式設計師用多執行緒程式設計技術來完成併發任務。
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是依賴於具體平臺的模組,其中只包含系統定義的訊號。