os.fork
有兩種方式來(lái)實(shí)現(xiàn)并發(fā)性,
一種方式是讓每個(gè)“任務(wù)"或“進(jìn)程”在單獨(dú)的內(nèi)在空間中工作,每個(gè)都有自已的工作內(nèi)存區(qū)域明刷。不過(guò),雖然進(jìn)程可在單獨(dú)的內(nèi)存空間中執(zhí)行满粗,但除非這些進(jìn)程在單獨(dú)的處理器上執(zhí)行辈末,否則,實(shí)際并不是“同時(shí)”運(yùn)行的映皆。是由操作系統(tǒng)把處理器的時(shí)間片分配給一個(gè)進(jìn)程挤聘,用完時(shí)間片后就需退出處理器等待另一個(gè)時(shí)間片的到來(lái)。
另一種方式是在在程序中指定多個(gè)“執(zhí)行線程”捅彻,讓它們?cè)谙嗤膬?nèi)存空間中工作组去。這稱為“多線程處理”。線程比進(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)假残。或稱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作為返回值颠印。一個(gè)現(xiàn)有進(jìn)程可以調(diào)用fork函數(shù)創(chuàng)建一個(gè)新進(jìn)程纲岭。由fork創(chuàng)建的新進(jìn)程被稱為子進(jìn)程(child process)。fork函數(shù)被調(diào)用一次但返回兩次线罕。兩次返回的唯一區(qū)別是子進(jìn)程中返回0值而父進(jìn)程中返回子進(jìn)程ID止潮。 對(duì)于程序,只要判斷fork的返回值钞楼,就知道自己是處于父進(jìn)程還是子進(jìn)程中喇闸。
子進(jìn)程是父進(jìn)程的副本,它將獲得父進(jìn)程數(shù)據(jù)空間窿凤、堆仅偎、棧等資源的副本衣厘。注意表谊,子進(jìn)程持有的是上述存儲(chǔ)空間的“副本”,這意味著父子進(jìn)程間不共享這些存儲(chǔ)空間觉渴,它們之間共享的存儲(chǔ)空間只有代碼段夯秃。
用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)。