1. 程式人生 > >FIFO 非阻塞寫+非阻塞讀+延時迴圈讀的一種方法

FIFO 非阻塞寫+非阻塞讀+延時迴圈讀的一種方法

用mkfifo在當前目錄下建立一個myfifo的有名管道


只執行非阻塞寫的程式 open引數為O_WRONLY | O_NONBLOCK
write失敗,這是man手冊裡面說明了的情況


如果open引數為O_RDWR | O_NONBLOCK
寫程式則可以立即返回
但是當執行完寫程式之後再執行讀程式,發現沒有從管道里讀出任何資料出來。
也就是說管道里面是空的,沒有存入任何資料。
寫程式中判斷了write的返回值,不是-1


如果open引數為O_WRONLY
則為寫阻塞
當執行讀程式的時候寫程式才會返回


當讀程式中的open引數為O_RDONLY
這時候是讀阻塞
當先執行讀程式的時候,寫程式是不是阻塞的無所謂,都可以讀到資料
但是,非阻塞的寫,是沒法讀到資料的。似乎非阻塞的寫沒有把資料寫入管道中。後面證明,是讀需要多次才能讀到,這中間存在了一個準備時間之類東西……


設定讀程式中open的引數為O_RDWR|O_NONBLOCK
這時候是非阻塞讀管道
當沒有任何寫程式執行的時候read返回-1,錯誤碼是EAGAIN
當寫是阻塞寫的時候,非阻塞讀依然不能讀到資料


寫的open引數為O_RDWR的時候即為非阻塞寫


阻塞讀+非阻塞寫的組合可以讀到資料,先進行讀
阻塞讀+阻塞寫的組合可以讀到資料,無所謂誰先執行
非阻塞讀+任何寫的方法,都不能讀到資料


在非阻塞讀的程式中加入while迴圈讀,直到讀出資料為止
這種情況下阻塞寫/非阻塞寫都可以讀到資料


說明管道資料準備好的時間很長……,一次基本上非常不靠譜
但是使用while讀基本上也就是阻塞讀了
因為會阻塞整個程式,因此需要有一個合理的超時機制來保證讀管道不阻塞,但是可以等一定的時間


等待時間需要用到定時器,簡單的可以使用select,但是不能用在一個程序裡,因為select會阻塞。
因此可以開另一個執行緒,定時,時間到,修改變數
在while讀中用變數作為while判斷條件,選擇退出while


這個定時器的超時時間是一種約束,要求在這段時間內必須向管道內寫入資料,不然則返回沒有讀到資料
因此,寫管道的程式所要保證的就是寫管道的時間間隔必須要小於這個超時時間
因為這個超時時間是很容易被修改的,因此只需要估計出寫管道的時間間隔就可以確定這個超時時間了。


這樣就形成了一個非阻塞寫+非阻塞讀_延時迴圈讀的結構