簡體   English   中英

為什么打開mkfifo-ed管道時我的程序會掛起?

[英]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_NONBLOCKopen

$ strace -P /tmp/myFIFO ./a.out
open("/tmp/myFIFO", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
...

關於如何打開FIFO的一些背景

只讀,沒有O_NONBLOCKopen塊,直到另一個進程打開FIFO進行寫入。 這是將fopen與模式參數"r"一起使用時的行為。

只寫,不帶O_NONBLOCKopen塊,直到另一個進程打開FIFO進行讀取。 這是將fopen與模式參數"w"一起使用時的行為。

只讀,使用O_NONBLOCKopen將立即返回。

僅寫操作, O_NONBLOCKopen返回錯誤,且errno設置為ENXIO除非另一個進程已打開FIFO進行讀取。

W. Richard Stevens的“ UNIX環境中的高級編程”中的信息。

打開FIFO的讀寫

在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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM