簡體   English   中英

如何在Linux中讀寫fifo(命名管道)?

[英]How to read and write to a fifo (named pipe) in Linux?

我正在嘗試打開一個fifo(命名管道)文件,然后將其寫入。 我似乎無法讓服務器看到“客戶端”寫入的內容。

注意:為簡單起見,我使用的術語類似於“客戶端-服務器”。 我意識到他們實際上只是同齡人,而且任何一方都可以關閉管道。

pipetest_server.c

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

int keep_going = 1;

static void signal_handler(int signum)
{
    keep_going = 0;
}

int main()
{
    int fd;
    char *myfifo = "/tmp/mypipe";
    char *line;
    ssize_t amount_read;
    ssize_t len;
    FILE *f;

    signal(SIGINT, signal_handler);
    signal(SIGABRT, signal_handler);
    signal(SIGTERM, signal_handler);

    // make pipe
    mkfifo(myfifo, 0666);

    // open it
    fd = open(myfifo, O_RDWR);

    // make non-blocking
    fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK);

    // make a file descriptor for pipe
    f = fdopen(fd, "rw");

    while(keep_going)
    {
        amount_read = getline(&line, &len, f);
        if (amount_read > 0)
            printf(line);
    }

    printf("quitting...\n");

    close(fd);

    unlink(myfifo);

    return 0;
}

然后:

$ gcc pipetest_server.c
$ ./a.out

在另一個終端:

$ ls -la /tmp/mypipe
prw-rw-r--. 1 myuser myuser 0 Nov 20 12:58 /tmp/mypipe

好的-此時,這里有一個管道。 現在解決問題

1)用回波寫入管道。 什么都沒發生

$ echo Hi >> /tmp/mypipe
<nothing comes out of the server>

2)給管子加襯管,顯示數據

$ cat /tmp/mypipe
Hi
<blinking cursor>

發生了什么....

服務器從不獲取數據,但是管道中包含數據。

3)當我關閉服務器時,管道消失了

<ctrl-C>
^Cquitting...

這告訴我服務器確實創建了管道並對其進行了控制。

4)我真的很想創建另一個程序來寫入管道

最終,我希望有另一個程序將寫入此管道,並且兩個程序將通過該管道進行通信。

注意:還有其他關於此的SO文章,但沒有一篇文章很重要。

更新-工作代碼

這是萬一有人追趕的最終解決方案。

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

static volatile sig_atomic_t keep_going = 1;

static void signal_handler(int signum)
{
    keep_going = 0;
}

int main()
{
    int fd;
    char *myfifo = "/tmp/mypipe";
    char *line;
    ssize_t amount_read;
    ssize_t len;
    FILE *f;

    signal(SIGINT, signal_handler);
    signal(SIGABRT, signal_handler);
    signal(SIGTERM, signal_handler);

    // make pipe
    mkfifo(myfifo, 0666);

    // open it
    fd = open(myfifo, O_RDWR);

    // make non-blocking
    fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK);

    // make a file descriptor for pipe
    f = fdopen(fd, "rw");

    while(keep_going)
    {
        amount_read = getline(&line, &len, f);
        if (amount_read > 0)
            printf(line);
        if (amount_read == -1)
        {
            clearerr(f);
        }
    }

    printf("quitting...\n");

    close(fd);

    unlink(myfifo);

    return 0;
}

問題是您已將文件描述符設置為非阻塞,然后使用fdopen在其上打開了一個FILE * Stdio FILE流不理解非阻塞I / O,因此在您第一次調用getline時,讀取將失敗(使用EWOULDBLOCK或EGAIN),並且FILE將進入錯誤狀態,並且getline將返回-1。 一旦FILE處於錯誤狀態,每個調用將立即返回-1,而無需實際嘗試再次讀取。

如果要實際使用非阻塞模式,則需要在getline返回-1之后調用clearerr(f) 您還應該檢查errno,以確保錯誤是EWOULDBLOCK或EAGAIN -如果存在真正的錯誤,則可能是其他錯誤。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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