2010-07-11 65 views
1

我正在嘗試在Linux中編寫一個簡單的守護進程,它將創建一個FIFO,然後收集寫入FIFO的任何內容,並在稍後將該數據寫入文件。無法正常使用Unix FIFO嗎?

我的期望是,一旦我的守護進程創建了FIFO,我就可以反覆執行「echo text>/myfifo」。完成後,我可以執行「echo quit>/myfifo」,我的程序將退出並將所有數據寫入磁盤。

我目前使用poll()來了解FIFO上有更多數據。這工作正常,直到我第一次回數據到FIFO。數據回覆良好,但我的調查在此之後不斷返回SIGHUP。

在每個進程寫入之後,是否需要重置(或關閉&重新打開)FIFO?我的代碼

僞代碼如下所示:

ret = fifo(my_fifo, mode); 
fd = open(my_fifo, O_RDONLY | O_NONBLOCK); 

polling.fd = fd; 
polling.events = POLLIN | POLLPRI; 

do { 
    ret = poll(&polling, 1, -1); 
    amt = read(fd, buf, bufsize); 
    // do stuff 
} while (!done); 

回答

2

你必須不斷重新打開FIFO,我想。我有一個程序,監視FIFO,以及監視器循環爲:

/* Implement monitor mode */ 
void sql_monitor(char *fifo) 
{ 
    if (chk_fifo(fifo) != 0) 
     cmd_error(E_NOTFIFO, fifo); 

    /* Monitor -- device is assumed to be a FIFO */ 
    while (1) 
    { 
     ctxt_newcontext(); 
     if (ctxt_setinput(fifo) != 0) 
      sql_exit(1); 
     sql_file(); 
     ctxt_endcontext(); 
    } 
} 

ctxt_newcontext()功能儲物箱的當前I/O狀態; ctxt_setinput()函數將輸入文件設置爲指定文件 - 在這種情況下爲FIFO。函數sql_file()從文件(FIFO)中讀取,直到到達結尾 - 文件關閉。 ctxt_endcontext()撤銷了什麼ctxt_newcontext()。重複該過程...距今約1990年

所以這段代碼已經出現,YES,你將需要保持關閉和讀取文件的末尾(每道工序後,如echo完成後重新開放FIFO寫入FIFO)。 (您還應該注意到,除非在沒有數據的情況下進程需要做其他事情,否則實際上不需要輪詢FIFO,read()調用將等到有數據返回時爲止。)

+0

是的,FIFO必須重新打開。很多人忘記了在同步模式下,打開FIFO會阻塞,直到通信的另一端也打開它。這是爲了使其可用於例如外殼重定向。所以在某種程度上,它表現得像一個連接。 – Dummy00001 2010-07-11 19:39:29