對(duì)Python進(jìn)程進(jìn)行全解析
下面對(duì)Python進(jìn)程進(jìn)行深入而仔細(xì)的學(xué)習(xí),首先先讓大家了解下什么是Python進(jìn)程,以及在對(duì)Python進(jìn)程進(jìn)行處理時(shí)注意的相關(guān)問(wèn)題,接下來(lái),就由我給大家進(jìn)行介紹學(xué)習(xí),僅供大家學(xué)習(xí)。
不過(guò),雖然進(jìn)程可在單獨(dú)的內(nèi)存空間中執(zhí)行,但除非這些Python進(jìn)程在單獨(dú)的處理器上執(zhí)行,否則,實(shí)際并不是“同時(shí)”運(yùn)行的。是由操作系統(tǒng)把處理器的時(shí)間片分配給一個(gè)進(jìn)程,用完時(shí)間片后就需退出處理器等待另一個(gè)時(shí)間片的到來(lái)。
另一種方式是在在程序中指定多個(gè)“執(zhí)行線程”,讓它們?cè)谙嗤膬?nèi)存空間中工作。這稱(chēng)為“多線程處理”。線程比進(jìn)程更有效,因?yàn)椴僮飨到y(tǒng)不必為每個(gè)線程創(chuàng)建單獨(dú)的內(nèi)存空間。新建進(jìn)程用os.fork函數(shù)。但它只在POSIX系統(tǒng)上可用,在windows版的python中,os模塊沒(méi)有定義os.fork函數(shù)。相反,windows程序員用多線程編程技術(shù)來(lái)完成并發(fā)任務(wù)。
os.fork函數(shù)創(chuàng)建進(jìn)程的過(guò)程是這樣的。程序每次執(zhí)行時(shí),操作系統(tǒng)都會(huì)創(chuàng)建一個(gè)新進(jìn)程來(lái)運(yùn)行程序指令。進(jìn)程還可調(diào)用os.fork,要求操作系統(tǒng)新建一個(gè)進(jìn)程。父進(jìn)程是調(diào)用os.fork函數(shù)的進(jìn)程。父進(jìn)程所創(chuàng)建的進(jìn)程叫子進(jìn)程。
每個(gè)進(jìn)程都有一個(gè)不重復(fù)的進(jìn)程ID號(hào)?;蚍Q(chēng)pid,它對(duì)進(jìn)程進(jìn)行標(biāo)識(shí)。子進(jìn)程與父進(jìn)程完全相同,子進(jìn)程從父進(jìn)程繼承了多個(gè)值的拷貝。如全局變量和環(huán)境變量。兩個(gè)進(jìn)程的唯一區(qū)別是fork的返回值。子進(jìn)程接收返回值0,而父進(jìn)程接收子進(jìn)程的pid作為返回值。
用os.fork創(chuàng)建的子進(jìn)程和父進(jìn)程作為異步的并發(fā)進(jìn)程而單獨(dú)執(zhí)行。異步是指它們各行其是,相互間不進(jìn)行同步;并發(fā)是指它們可同時(shí)執(zhí)行。所以我們無(wú)法知道子進(jìn)程和父進(jìn)程的相對(duì)速度。
os.wait函數(shù)用于等待子進(jìn)程結(jié)束(只適用于UNIX兼容系統(tǒng))。該函數(shù)返回包含兩個(gè)元素的元組,包括已完成的子進(jìn)程號(hào)pid。以及子進(jìn)程的退出狀態(tài),返回狀態(tài)為0,表明子進(jìn)程成功完成。返回狀態(tài)為正整數(shù)表明子進(jìn)程終止時(shí)出錯(cuò)。
如沒(méi)有子進(jìn)程,會(huì)引發(fā)OSError錯(cuò)誤。os.wait要求父進(jìn)程等待它的任何一個(gè)子進(jìn)程結(jié)束執(zhí)行,然后喚醒父進(jìn)程。要指示父進(jìn)程等候一個(gè)指定的子進(jìn)程終止,可在父進(jìn)程中使用os.waitpid函數(shù)(只適用于unix兼容系統(tǒng))。
它可等候一個(gè)指定進(jìn)程結(jié)束,然后返回一個(gè)雙元素元組,其中包括子進(jìn)程的pid和子進(jìn)程的退出狀態(tài)。函數(shù)調(diào)用將pid作為第一個(gè)參數(shù)傳遞。并將一個(gè)選項(xiàng)作為第二個(gè)選項(xiàng),如果第一個(gè)參數(shù)大于0,則waitpid會(huì)等待該pid結(jié)束,如果第一個(gè)參數(shù)是-1,則會(huì)等候所有子進(jìn)程,也就和os.wait一樣。
用os.system 和 os.exec函數(shù)族來(lái)執(zhí)行系統(tǒng)命令和其它程序。os.system使用shell來(lái)執(zhí)行系統(tǒng)命令,然后在命令結(jié)束之后把控制權(quán)返回給原始進(jìn)程;os.exec函數(shù)族在執(zhí)行完命令后不將控制權(quán)返回給調(diào)用進(jìn)程。它會(huì)接管Python進(jìn)程,pid不變。這兩個(gè)函數(shù)支持unix和windows平臺(tái)。
os.popen()函數(shù)可執(zhí)行命令,并獲得命令的stdout流。函數(shù)要取得兩個(gè)參數(shù),一個(gè)是要執(zhí)行的命令,另一個(gè)是調(diào)用函數(shù)所用的模式。如“r"只讀模式。os.popen2()函數(shù)執(zhí)行命令,并獲得命令的stdout流和stdin流。函數(shù)返回一個(gè)元組,其中包含有兩個(gè)文件對(duì)象,一個(gè)對(duì)象對(duì)應(yīng)stdin流,一個(gè)對(duì)象對(duì)應(yīng)stdout流。
進(jìn)程使用IPC機(jī)制在進(jìn)程間傳遞信息,一種IPC機(jī)制是“管道”,它是一種類(lèi)似于文件的對(duì)象,提供單向通信渠道。父進(jìn)程可打開(kāi)一個(gè)管道,再分支一個(gè)子進(jìn)程。父進(jìn)程使用管道將信息寫(xiě)入(發(fā)送到)子進(jìn)程,而子進(jìn)程使用管道從父進(jìn)程讀取信息。在python中使用os.pipe函數(shù)創(chuàng)建管道。
os._exit()類(lèi)似于sys.exit(),但它不執(zhí)行任何的清除工作(例如刷新緩沖區(qū))。所以os._exit()尤其適用于退出子進(jìn)程。如果程序使用sys.exit(),操作系統(tǒng)會(huì)回收父進(jìn)程或其它子進(jìn)程可能仍然需要的資源。傳給os._exit()函數(shù)的參數(shù)必須是進(jìn)程的退出狀態(tài)。退出狀態(tài)為0,表示正常終止。
進(jìn)程也可用信號(hào)進(jìn)行通信。所謂“信號(hào)”,是操作系統(tǒng)采取異步方式傳給程序的消息。如CTRL+C會(huì)傳遞一個(gè)“中斷信號(hào)”,通常該信號(hào)導(dǎo)致程序中止。然而程序完全可以指定用不同的行動(dòng)來(lái)響應(yīng)任何一個(gè)信號(hào)。在信號(hào)處理中,程序要接收信號(hào),并根據(jù)那個(gè)信號(hào)采取一項(xiàng)行動(dòng)。
錯(cuò)誤(例如向已關(guān)閉管道寫(xiě)入)、事件(例如計(jì)時(shí)器變成0)以及用戶輸入(例如按ctrl+c)都會(huì)產(chǎn)生信號(hào)。針對(duì)每個(gè)信號(hào),每個(gè)python程序都有一個(gè)默認(rèn)的信號(hào)處理程序,并不是所有操作系統(tǒng)。
都能從一個(gè)正在運(yùn)行的程序創(chuàng)建單獨(dú)的進(jìn)程,所以,進(jìn)程管理是移植性最差的一項(xiàng)Python進(jìn)程特性。每個(gè)系統(tǒng)都定義了特有信號(hào)集。signal是依賴于具體平臺(tái)的模塊,其中只包含系統(tǒng)定義的信號(hào)。
【編輯推薦】