[英]Why does my program hang when opening a mkfifo-ed pipe?
我使用mkfifo創建一個命名管道。 然后,我使用以下程序將其打開。 但是,該程序掛在行“ fopen”。 這里有什么問題嗎?
int main(int argc, char** argv) {
char* line = "hello, world!";
FILE* fp = fopen("/tmp/myFIFO", "rw");
fprintf(fp, line);
fclose(fp);
return 0;
}
嘗試將"w"
作為打開模式。 "rw"
對於fopen
來說不是有效的模式參數,即使它是,您也可能不想同時在同一進程中讀取和寫入FIFO(盡管有可能,請參見下文)。
順便說一句,用於打開文件以供讀取和寫入的正確模式參數是"r+"
或"w+"
( 有關差異,請參見此問題的答案)。
該程序將正確寫入FIFO:
#include <stdio.h>
int main(int argc, char** argv) {
FILE* fp = fopen("/tmp/myFIFO", "w");
fprintf(fp, "Hello, world!\n");
fclose(fp);
return 0;
}
請注意,上述程序中的fopen
將阻塞,直到打開FIFO進行讀取為止。 當它阻塞時,在另一個終端中運行它:
$ cat /tmp/myFIFO
Hello, world!
$
之所以阻塞,是因為fopen
不會通過O_NONBLOCK
來open
:
$ strace -P /tmp/myFIFO ./a.out
open("/tmp/myFIFO", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
...
只讀,沒有O_NONBLOCK
: open
塊,直到另一個進程打開FIFO進行寫入。 這是將fopen
與模式參數"r"
一起使用時的行為。
只寫,不帶O_NONBLOCK
: open
塊,直到另一個進程打開FIFO進行讀取。 這是將fopen
與模式參數"w"
一起使用時的行為。
只讀,使用O_NONBLOCK
: open
將立即返回。
僅寫操作, O_NONBLOCK
: open
返回錯誤,且errno
設置為ENXIO
除非另一個進程已打開FIFO進行讀取。
W. Richard Stevens的“ UNIX環境中的高級編程”中的信息。
在Linux中也可以打開FIFO以在同一過程中進行讀寫。 Linux FIFO手冊頁指出:
在Linux下,打開FIFO進行讀寫將在阻塞和非阻塞模式下都成功。 POSIX未定義此行為。 在沒有可用的讀取器的情況下,可用於打開FIFO進行寫入。 使用連接兩端進行通信的進程應非常小心,以避免死鎖。
這是一個寫入和讀取相同FIFO的程序:
#include <stdio.h>
int main(int argc, const char *argv[]) {
char buf[100] = {0};
FILE* fp = fopen("/tmp/myFIFO", "r+");
fprintf(fp, "Hello, world!\n");
fgets(buf, sizeof(buf), fp);
printf("%s", buf);
fclose(fp);
return 0;
}
它不會阻塞,並立即返回:
$ gcc fifo.c && ./a.out
Hello, world!
請注意,這是不可移植的,並且可能無法在Linux以外的操作系統上使用。
該過程將一直阻塞,直到管道的另一端打開為止。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.