嵌入式Linux基本教程中,Linux有名管道的堵塞是一個(gè)令人困擾的問(wèn)題,下面我們就來(lái)講一下這個(gè)問(wèn)題是如何產(chǎn)生的,以更好地掌握其內(nèi)部的邏輯關(guān)系。
一、問(wèn)題由來(lái)
在先前操作有名管道相關(guān)試驗(yàn)時(shí),發(fā)現(xiàn)有名管道中存在有堵塞的問(wèn)題,該堵塞是在調(diào)用open函數(shù)打開(kāi)有名管道文件時(shí)發(fā)生,具體表現(xiàn)形式如下:
情況一:
有兩份代碼jack和rose,其通過(guò)編譯運(yùn)行實(shí)現(xiàn)兩個(gè)進(jìn)程之間的通信,兩份代碼均為調(diào)用open函數(shù)打開(kāi)有名管道文件,其中jack作為數(shù)據(jù)讀取進(jìn)程,用于讀取rose發(fā)送過(guò)來(lái)的數(shù)據(jù),且jack中open的有名管道打開(kāi)方式是以只讀方式打開(kāi),rose中的open有名管道的打開(kāi)方式是以只寫(xiě)方式打開(kāi),部分代碼書(shū)寫(xiě)如下:
Jack部分
Rose部分
嵌入式Linux基本教程在Linux中如只先運(yùn)行其中的某個(gè)程序時(shí),不能得到打印信息,但兩個(gè)程序都執(zhí)行后,Linux終端上得到兩端的提示信息打印。如圖1、2
圖1 只有一端執(zhí)行時(shí)表現(xiàn)形式
情況二:
兩份代碼jack和rose,調(diào)用open函數(shù)打開(kāi)有名管道時(shí),如的打開(kāi)的方式為可讀可寫(xiě)方式(O_RDWR),則open函數(shù)再會(huì)堵塞,提示信息直接打印。部分代碼如下
Jack部分代碼
Rose部分代碼
圖示如圖2
情況總結(jié):
調(diào)用 open()打開(kāi)有名管道的進(jìn)程open函數(shù)處可能會(huì)被阻塞。但如果同時(shí)以讀寫(xiě)方式 (O_RDWR)打開(kāi),則一定不會(huì)導(dǎo)致阻塞;如果以只讀方式 ( O_RDONLY ) 打開(kāi),則調(diào)用 open() 函數(shù)的進(jìn)程將會(huì)被阻塞直到有寫(xiě)方打開(kāi)管道;同樣以寫(xiě)方式 ( O_WRONLY ) 打開(kāi)也會(huì)阻塞直到有讀方打開(kāi)管道。
二、問(wèn)題原因
在用open打開(kāi)FIFO時(shí)有可能會(huì)阻塞,原因就是當(dāng)前只有讀端或?qū)懚舜嬖凇Q句話說(shuō),如果程序在打開(kāi)FIFO時(shí)指定了只讀方式/只寫(xiě)方式,那么該進(jìn)程對(duì)于打開(kāi)的FIFO來(lái)說(shuō)就是一個(gè)讀端/寫(xiě)端。如果指定的是讀寫(xiě)方式,那么進(jìn)程即是讀端又是寫(xiě)端。嵌入式Linux基本教程表示這就好比如是一根水管,當(dāng)水管的兩端都打開(kāi)時(shí),水管才能通水,反之只要有一端不同,水管就會(huì)堵塞。
三、有名管道讀寫(xiě)數(shù)據(jù)問(wèn)題
從FIFO中讀數(shù)據(jù)時(shí)(用read函數(shù)),如果沒(méi)有數(shù)據(jù),默認(rèn)是阻塞等待,直到有數(shù)據(jù)被寫(xiě)入FIFO。如果read函數(shù)返回0,說(shuō)明該FIFO所有的寫(xiě)端都已關(guān)閉,程序要做相應(yīng)的處理。向FIFO寫(xiě)入數(shù)據(jù)時(shí)(使用write函數(shù)),如果FIFO有足夠空間,write函數(shù)會(huì)返回寫(xiě)入的字節(jié)數(shù);如果空間不夠,write函數(shù)會(huì)阻塞,直到寫(xiě)完為止。當(dāng)所有的讀端都關(guān)閉時(shí),再向FIFO寫(xiě)數(shù)據(jù)會(huì)出錯(cuò)。內(nèi)核會(huì)向?qū)戇M(jìn)程發(fā)管道斷裂的信號(hào)(SIGPIPE), 從而終止該進(jìn)程。
有關(guān)嵌入式Linux基本教程中Linux有名管道的堵塞問(wèn)題就先說(shuō)到這里,如果感興趣的話,可以到粵嵌系統(tǒng)培訓(xùn)相關(guān)的知識(shí)。