2011-08-13 76 views
14

當我在Python中打開FIFO(命名管道)進行寫入時,發生了一些非常奇怪的事情。考慮會發生什麼,當我試圖打開一個FIFO用於在交互式解釋寫着:如何正確寫入Python中的FIFO?

>>> fifo_write = open('fifo', 'w') 

上面一行塊,直到我打開另一個解釋,並鍵入以下內容:

>>> fifo_read = open('fifo', 'r') 
>>> fifo.read() 

我不明白爲什麼我不得不等待管道打開閱讀,但讓我們跳過這一點。上述代碼將會阻塞,直到有數據可用爲止。但是假設我回到第一翻譯窗口,鍵入:

>>> fifo_write.write("some testing data\n") 
>>> fifo_write.flush() 

預期的行爲是在第二解釋調用read將會迴歸,我們會看到屏幕上的數據,但不發生在我身上。如果我撥打os.fsync,會發生以下情況:

>>> import os 
>>> fifo_write.flush() 
>>> os.fsync(fifo_write.fileno()) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
OSError: [Errno 22] Invalid argument 

而且fifo閱讀器仍在等待。但是,如果我撥打fifo_writer.close(),那麼數據就會被刷新。如果我使用一個shell命令喂管:

$ echo "some data" > fifo 

然後將讀卡器輸出是:

>>> fifo_read.read() 
'some data\n' 

有沒有人遇到過這個?如果是的話,是否有解決方法?我目前的操作系統是Ubuntu 11.04和Linux 2.6.38。

+1

你是如何創建fifo的? – OneOfOne

+0

在FIFO上使用「os.mkfifo('fifo')」或shell「mkfifo fifo」 –

+1

'fsync()'是沒有意義的;沒有數據存儲在光盤上(除非在非常奇怪的情況下*可能*在交換中)。 –

回答

11

read()直到到達EOF時才返回。

您可以嘗試指定要讀取的字節數,如read(4)。這將仍然阻塞,直到寫入足夠的字節,所以生產者必須至少寫入那麼多字節,然後調用flush()

+0

謝謝你,爲'read'方法添加一個參數解決了這個問題,仍然需要刷新雖然.. –

+2

@ThiadodeArruda究竟是什麼論點? – n611x007

2

爲了避免沖洗的需要,打開該文件沒有緩衝:

fifo_read = open('fifo', 'r', 0) 

,將刪除高水平的緩衝。數據直接進入操作系統,作爲一個fifo,他們永遠不會真正寫入磁盤,而是直接通過fifo緩衝區傳遞給讀寫器,因此您不需要同步。

當然,您應該先在shell中創建fifo,然後在os.mkfifo()mkfifo處進行創建,就像您在評論中指出的一樣。