一、簡(jiǎn)介
我們將一個(gè)正在運(yùn)行的程序稱為進(jìn)程。每個(gè)進(jìn)程都有它自己的系統(tǒng)狀態(tài),包含內(nèi)存狀態(tài)、打開文件列表、追蹤指令執(zhí)行情況的程序指針以及一個(gè)保存局部變量的調(diào)用棧。通常情況下,一個(gè)進(jìn)程依照一個(gè)單序列控制流順序執(zhí)行,這個(gè)控制流被稱為該進(jìn)程的主線程。在任何給定的時(shí)刻,一個(gè)程序只做一件事情。
一個(gè)程序可以通過(guò)Python庫(kù)函數(shù)中的os或subprocess模塊創(chuàng)建新進(jìn)程(例如os.fork()或是subprocess.Popen())。然而,這些被稱為子進(jìn)程的進(jìn)程卻是獨(dú)立運(yùn)行的,它們有各自獨(dú)立的系統(tǒng)狀態(tài)以及主線程。因?yàn)檫M(jìn)程之間是相互獨(dú)立的,因此它們同原有的進(jìn)程并發(fā)執(zhí)行。這是指原進(jìn)程可以在創(chuàng)建子進(jìn)程后去執(zhí)行其它工作。
雖然進(jìn)程之間是相互獨(dú)立的,但是它們能夠通過(guò)名為進(jìn)程間通信(IPC)的機(jī)制進(jìn)行相互通信。一個(gè)典型的模式是基于消息傳遞,可以將其簡(jiǎn)單地理解為一個(gè)純字節(jié)的緩沖區(qū),而send()或recv()操作原語(yǔ)可以通過(guò)諸如管道(pipe)或是網(wǎng)絡(luò)套接字(network socket)等I/O通道傳輸或接收消息。還有一些IPC模式可以通過(guò)內(nèi)存映射(memory-mapped)機(jī)制完成(例如mmap模塊),通過(guò)內(nèi)存映射,進(jìn)程可以在內(nèi)存中創(chuàng)建共享區(qū)域,而對(duì)這些區(qū)域的修改對(duì)所有的進(jìn)程可見。
多進(jìn)程能夠被用于需要同時(shí)執(zhí)行多個(gè)任務(wù)的場(chǎng)景,由不同的進(jìn)程負(fù)責(zé)任務(wù)的不同部分。然而,另一種將工作細(xì)分到任務(wù)的方法是使用線程。同進(jìn)程類似,線程也有其自己的控制流以及執(zhí)行棧,但線程在創(chuàng)建它的進(jìn)程之內(nèi)運(yùn)行,分享其父進(jìn)程的所有數(shù)據(jù)和系統(tǒng)資源。當(dāng)應(yīng)用需要完成并發(fā)任務(wù)的時(shí)候線程是很有用的,但是潛在的問(wèn)題是任務(wù)間必須分享大量的系統(tǒng)狀態(tài)。
當(dāng)使用多進(jìn)程或多線程時(shí),操作系統(tǒng)負(fù)責(zé)調(diào)度。這是通過(guò)給每個(gè)進(jìn)程(或線程)一個(gè)很小的時(shí)間片并且在所有活動(dòng)任務(wù)之間快速循環(huán)切換來(lái)實(shí)現(xiàn)的,這個(gè)過(guò)程將CPU時(shí)間分割為小片段分給各個(gè)任務(wù)。例如,如果你的系統(tǒng)中有10個(gè)活躍的進(jìn)程正在執(zhí)行,操作系統(tǒng)將會(huì)適當(dāng)?shù)膶⑹种坏腃PU時(shí)間分配給每個(gè)進(jìn)程并且循環(huán)地在十個(gè)進(jìn)程之間切換。當(dāng)系統(tǒng)不止有一個(gè)CPU核時(shí),操作系統(tǒng)能夠?qū)⑦M(jìn)程調(diào)度到不同的CPU核上,保持系統(tǒng)負(fù)載平均以實(shí)現(xiàn)并行執(zhí)行。
利用并發(fā)執(zhí)行機(jī)制寫的程序需要考慮一些復(fù)雜的問(wèn)題。復(fù)雜性的主要來(lái)源是關(guān)于同步和共享數(shù)據(jù)的問(wèn)題。通常情況下,多個(gè)任務(wù)同時(shí)試圖更新同一個(gè)數(shù)據(jù)結(jié)構(gòu)會(huì)造成臟數(shù)據(jù)和程序狀態(tài)不一致的問(wèn)題(正式的說(shuō)法是資源競(jìng)爭(zhēng)的問(wèn)題)。為了解決這個(gè)問(wèn)題,需要使用互斥鎖或是其他相似的同步原語(yǔ)來(lái)標(biāo)識(shí)并保護(hù)程序中的關(guān)鍵部分。舉個(gè)例子,如果多個(gè)不同的線程正在試圖同時(shí)向同一個(gè)文件寫入數(shù)據(jù),那么你需要一個(gè)互斥鎖使這些寫操作依次執(zhí)行,當(dāng)一個(gè)線程在寫入時(shí),其他線程必須等待直到當(dāng)前線程釋放這個(gè)資源。
新聞熱點(diǎn)
疑難解答
圖片精選