2016-01-12 98 views
0

嘗試從多個FIFO中讀取時,我遇到了一個非常惱人的問題。我有1個進程等待來自fifo的結構,很少有進程將這些結構發送給信號。在第一次閱讀後,我無法從任何信號中讀出更多。它看起來像程序凍結。無法從多個FIFO中讀取

發送進程具有這主要與

myfifo = '/tmp/myfifo{0}' //{0} is a number that every process has individual. 
mkfifo(myfifo, 0666); 
fd = open(myfifo, O_WRONLY); 
write(fd, &demon1 , sizeof(demon1)); 
close(fd); 
while (1) 
{ 
} 

而這signal_handler

void signal_handler(int signum) 
{ 
    if (signum == SIGUSR1) 
    { 
     //some declarations here 
     mkfifo(myfifo, 0666); 
     fd = open(myfifo, O_WRONLY | O_NONBLOCK); 
     write(fd, &demon1 , sizeof(demon1)); 
    } 
} 

在閱讀過程中有

myfifo[i] = /tmp/myfifo{0} // {0} is i which is the number of process that sends. 

while(1) 
{ 
    for(i=0;i<n;i++) 
    { 
     fd = open(myfifo[i], O_RDONLY | O_NONBLOCK); 
     r = read(fd, &demon1, sizeof(demon1)); 
     if(r > 1) 
     { 
      //printf struct elements 
     } 

    } 
    } 
+0

請發送一個簡單的工作示例。例如,您是否在打開_reading process_後再次關閉每個fd?否則,你將很快用完文件描述符 – Ctx

+0

,這大部分是其他事物正在打印和設置目錄的一切。 – Thomas

+0

我建議讀取'man 7 fifo'的輸出,特別是關於在非阻塞模式下打開FIFO的部分。我認爲當FIFO的另一端沒有打開時,你的只寫,非阻塞的'open'將會失敗,並帶有errno'ENXIO'。 –

回答

1

你不打開後關閉filedescriptors和閱讀:

while(1) 
{ 
    for(i=0;i<n;i++) 
    { 
     fd = open(myfifo[i], O_RDONLY | O_NONBLOCK); 
     r = read(fd, &demon1, sizeof(demon1)); 
     if(r > 1) 
     { 
      //printf struct elements 
     } 

這裏缺少一個close(fd)

} 
} 

由於開放是非阻塞的,很快會達到每過程FDS的最大數量,以及隨後的打開將失敗。

+0

這仍然沒有幫助,如果我不會發送到myfifo [0]其他fifos不會被讀取 – Thomas

+0

@Thomas對不起,我不明白這個評論,請你詳細說明會發生什麼? – Ctx

+0

myfifo [0]有路徑到第一個fifo,如果我不讀取它,我不會檢查下一個。 例如,如果我首先發送myfifo [2](第三條路徑),它將等待unipher myfifo [0]和myfifo [1]被讀取。 – Thomas

1

您打開循環內的管道。這樣,你很快就會耗盡文件描述符(如果你檢查了open()的錯誤結果,你會看到這些描述符)。

我建議打開循環外的所有FIFO,將文件描述符存儲在數組中,然後只讀取它們中的每一個,但是...讀取將會阻塞。查看select(2)找出哪個FIFO有數據。

另一種解決方案是單個FIFO,寫入過程應該在消息中發送它的ID。這樣,主流程只需要聽一個單一的FIFO。如果它想知道誰發送了消息,它可以查看消息中的ID。這裏的問題是:你需要某種鎖定,或者幾個進程將同時寫入FIFO,並且它們的數據可能被混淆(這取決於FIFO緩衝區)。