2016-08-22 92 views
0

我有一個在Linux中的命名管道,我想從Python讀取它。問題是python進程不斷消耗一個核心(100%)。我的代碼如下:Python閱讀命名PIPE

FIFO = '/var/run/mypipe' 
os.mkfifo(FIFO) 
with open(FIFO) as fifo: 
    while True: 
     line = fifo.read() 

我要問,如果「睡眠」會幫助的情況或處理從管會損失一些輸入數據。我無法控制輸入,所以我不知道數據輸入的頻率。我讀了關於選擇和民意調查,但我沒有找到任何我的問題的例子。最後,我想問一下,100%的使用是否會對數據輸入產生任何影響(丟失或什麼?)。

編輯:我不想打破循環。我希望這個過程持續運行,並'聽到'來自管道的數據。

+0

什麼'打印(線)'輸出的循環?還有你如何寫作? –

+0

腳本等待來自另一個進程的數據。如果它帶有一個特定字符串的字符串,它會執行一些API調用。 – user1005633

+0

因此,當你打印(行)時,你總是看到循環中的數據? –

回答

6

在典型的UNIX方式,read(2)返回0字節,以指示結束文件這可能意味着:

  • 有在文件
  • 沒有更多的字節的插座的另一端具有關閉連接
  • 作家已經完成了管

在你的情況,fifo.read()將返回一個空字符串,因爲作者已經關閉了文件描述符。

你應該檢測的情況下,打破了你的循環:

reader.py

import os 
import errno 

FIFO = 'mypipe' 

try: 
    os.mkfifo(FIFO) 
except OSError as oe: 
    if oe.errno != errno.EEXIST: 
     raise 

print("Opening FIFO...") 
with open(FIFO) as fifo: 
    print("FIFO opened") 
    while True: 
     data = fifo.read() 
     if len(data) == 0: 
      print("Writer closed") 
      break 
     print('Read: "{0}"'.format(data)) 

例會議

1號航站樓

$ python reader.py 
Opening FIFO... 
<blocks> 

2號航站樓

$ echo -n 'hello' > mypipe 

1號航站樓

FIFO opened 
Read: "hello" 
Writer closed 
$ 

更新1 - 不斷地重新打開

表明您想保留名單即使在作家關閉之後,也可能會寫入管道。

爲了有效地做到這一點,你可以(也應該)採取的是

通常情況下,打開FIFO模塊,直至另一端也打開了事實。

在這裏,我在openread循環周圍添加了另一個循環。這樣一來,一旦管道被關閉,該代碼將嘗試重新打開它,這將阻止,直到另一位作家打開管道:

import os 
import errno 

FIFO = 'mypipe' 

try: 
    os.mkfifo(FIFO) 
except OSError as oe: 
    if oe.errno != errno.EEXIST: 
     raise 

while True: 
    print("Opening FIFO...") 
    with open(FIFO) as fifo: 
     print("FIFO opened") 
     while True: 
      data = fifo.read() 
      if len(data) == 0: 
       print("Writer closed") 
       break 
      print('Read: "{0}"'.format(data)) 

1號航站樓

$ python reader.py 
Opening FIFO... 
<blocks> 

2號航站樓

$ echo -n 'hello' > mypipe 

1號航站樓

FIFO opened 
Read: "hello" 
Writer closed 
Opening FIFO... 
<blocks> 

2號航站樓

$ echo -n 'hello' > mypipe 

1號航站樓

FIFO opened 
Read: "hello" 
Writer closed 
Opening FIFO... 
<blocks> 

...等等。


您可以通過閱讀man頁管道瞭解更多:

+0

我不想打破循環。我想連續閱讀。該腳本等待來自另一個進程的數據。如果它帶有一個特定字符串的字符串,它會執行一些API調用... – user1005633

+0

*「我想連續閱讀它。」*不,你不知道。這就是導致100%CPU利用率的原因。正如你可以在我的更新示例中看到的,「打開」阻止,直到有一個作者。你想要做的就是關閉管道,然後在你重新打開它時允許「打開」阻塞。查看我的更新1. –

+0

我強烈建議您充分閱讀我已鏈接的手冊頁,並且完全理解管道/ fifo的開放,讀取和寫入語義。 –