2015-10-03 200 views
0

我試圖將字符串發送到unix中的管道。當我逐行調試過程時,調用mkfifo()將在與源代碼相同的目錄中創建該文件。但是,當我到達open()調用時,調試器將不再能夠繼續。我不知道爲什麼它無法訪問管道文件。將字符串寫入管道

這裏是有問題的代碼:

#include <fcntl.h> 
#include <sys/stat.h> 
#include <sys/types.h> 
#include <unistd.h> 

int main() 
{ 
int fd; 
char * myfifo = "myfifo"; 

/* create the FIFO (named pipe) */ 
mkfifo(myfifo, 0666); 

/* write "Hi" to the FIFO */ 
fd = open(myfifo, O_WRONLY); 
write(fd, "Hi", sizeof("Hi")); 
close(fd); 

/* remove the FIFO */ 
unlink(myfifo); 

return 0; 
} 

任何建議表示讚賞。謝謝。

+0

經常檢查從返回的值open()和write()和mkfifo()這樣的檢查會告訴程序什麼失敗(在這種情況下,可能是write(),但是,在程序的第一次運行後,任何連續運行都會失敗mkfifo (),因爲fifo已經存在 – user3629249

回答

4

通常情況下,FIFO必須在兩端同時打開,然後任何一方纔能繼續。既然你沒有提及讀者的任何內容,最可能的答案是你沒有得到一個,或者你還沒有設置它。一旦你這樣做,公開將被允許繼續。

+0

我確實有一個reader.c文件,並且編譯。我將如何去同時打開它們?到目前爲止,我已經將作者和讀者編譯成單獨的可執行文件並運行它們。我將更新我的代碼以包含reader.c – Johnny

+1

@Johnny最簡單的解決方案:打開兩個終端,並在每個終端中運行一個? – immibis

+1

@Johnny你只需要讀者和作者同時運行。例如,啓動您的閱讀器進程,然後在另一個終端中啓動您的寫入器進程。一旦兩者都在運行,他們將被允許繼續。 –

1

mkfifo(3)路線fifo(7)內容如下:

內核維護只有一個管道對象由至少一個進程打開的每個FIFO特殊文件。在數據通過之前,FIFO必須在兩端打開(讀和寫)。 通常,打開FIFO模塊直到另一端也打開。

沒有爲非阻塞的溶液

進程可以在非阻塞模式下打開一個FIFO。在這種情況下,即使沒有人在寫入側打開,只讀的打開也會成功,除非另一端已經打開,否則打開僅寫入將失敗與ENXIO(沒有這樣的設備或地址)。

所以,你可以派生另一個進程閱讀:

#include <fcntl.h> 
#include <sys/stat.h> 
#include <sys/types.h> 
#include <unistd.h> 


long strlen(char * c){ 
    return c[0] == 0 ? 0 : 1 + strlen(++c); 
} 

int main() 
{ 
    int fd; 
    int fr; 
    char buf[3]; 
    char * MESSAGE = "Hi\n"; 
    char * myfifo = "myfifo"; 

    /* create the FIFO (named pipe) */ 
    mkfifo(myfifo, 0666); 


    int msglen = strlen(MESSAGE); 
    int child = fork(); 
    if (child == 0){ 
     /* read "Hi" from the FIFO (CHILD)*/ 
     fr = open(myfifo, O_RDONLY); 
     read(fr, buf, msglen); 
     write(1, buf, msglen); 
     close(fr); 

    } else { 
     /* write "Hi" to the FIFO (PARENT)*/ 
     fd = open(myfifo, O_WRONLY); 
     write(fd, MESSAGE, sizeof(char) * msglen); 
     close(fd); 

     /* remove the FIFO */ 
     wait(child); 
     unlink(myfifo); 
    } 
    return 0; 
} 

我猜你有你寫之前打開兩端。

0

這裏是從mkfifo手冊頁的摘錄()查看我的筆記在年底

mkfifo() makes a FIFO special file with name pathname. mode 
    specifies the FIFO's permissions. It is modified by the process's 
    umask in the usual way: the permissions of the created file are (mode 
    & ~umask). 

    A FIFO special file is similar to a pipe, except that it is created 
    in a different way. Instead of being an anonymous communications 
    channel, a FIFO special file is entered into the filesystem by 
    calling mkfifo(). 

    Once you have created a FIFO special file in this way, any process 
    can open it for reading or writing, in the same way as an ordinary 
    file. However, it has to be open at both ends simultaneously before 
    you can proceed to do any input or output operations on it. Opening 
    a FIFO for reading normally blocks until some other process opens the 
    same FIFO for writing, and vice versa. See fifo(7) for nonblocking 
    handling of FIFO special files. 

注:有重要的兩個細節:

1) the 'mode' parameter is modified by the value of 'umask' 
2) both ends of the fifo must be open at the same time 
    before any I/O operations can be performed.