LINUX FIFO 命名管道 (IPC) 在特定文件描述符处停止写入/读取消息

Posted

技术标签:

【中文标题】LINUX FIFO 命名管道 (IPC) 在特定文件描述符处停止写入/读取消息【英文标题】:LINUX FIFO named pipe (IPC) stops writing/reading message at specific file descriptor 【发布时间】:2021-10-13 11:28:08 【问题描述】:

我正在使用命名管道(fifo 模式)在两个不相关的进程(不是来自同一个父进程)之间进行通信。 该程序有效。但是,桩文件似乎是有限的

作者的输出:

Wrote to file. fd = 3
Wrote to file. fd = 3
...... other output ...
Wrote to file. fd = 3
Wrote to file. fd = 3

阅读器的输出是:

fd: 3. Received buffer: hello
fd: 4. Received buffer: hello
...... other output ...
fd: 1021. Received buffer: hello
fd: 1022. Received buffer: hello
fd: 1023. Received buffer: hello

我的问题:在fd 1023,阅读器似乎停止从文件中读取(没有fd 1024、1025 等)。当它发生时,作者 STOP WRITING (log "Wrote to file.fd = 3" 停止显示)

我尝试了不同的msg 值(“嗨”、“你在哪里”……),但作者总是停在fd 1023

我真的不明白为什么。你能给我解释一下吗? 非常感谢!

这是我的代码: 作者:

#include <stdio.h>
#include <stdlib.h> /* exit functions */
#include <unistd.h> /* read, write, pipe, _exit */
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <unistd.h>

int main()

    int fd;
    char * myfifo = "/tmp/myfifo";
    char msg[] = "hello";

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

    fd = open(myfifo, O_WRONLY);
    if (fd < 0) 
        return;
    

    while(1) 
        write(fd, msg, sizeof(msg));
        printf("Wrote to file. fd = %d\n", fd);
        sleep(1);
    
    close(fd);

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

    return 0;

读者:

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

#define MAX_BUF 500

int main()

    int fd;
    char * myfifo = "/tmp/myfifo";
    char buf[MAX_BUF];

    while(1) 
        /* open, read, and display the message from the FIFO */
        fd = open(myfifo, O_RDONLY);

        if (fd != -1) 
            if (read(fd, buf, sizeof(buf)) > 0) 
                printf("fd: %d. Received buffer: %s\n", fd, buf);
            
        
        sleep(0.2);
    
    close(fd);

    return 0;

【问题讨论】:

你为什么一直循环调用open?您无需这样做即可使用管道,并且一次可以打开的文件数量有限制。 【参考方案1】:

我真的不明白为什么。你能帮我解释一下吗?

您的系统上打开的文件描述符的数量是有限制的。可以使用 ulimit -n 在 shell 中检查限制。它是可配置的。请参阅help ulimitman limits.conf

在您的系统上,打开文件描述符的最大数量似乎是 1024(我的也是!)打开更多将返回 -1errno=EMFILE

您的reader 程序在循环中打开新的文件描述符。在达到打开文件描述符的限制后,open 开始重新调整-1,因为if (fd != -1) 使程序停止输出任何东西。

【讨论】:

谢谢卡米尔库克。你是对的。我修复了阅读器并在问题会话中进行了更新。非常感谢 UPDATE: This is the correct main function for the reader: 哦不,那太恐怖了。只需open(...); while (1) read();。不清楚为什么需要循环打开,只打开一次。

以上是关于LINUX FIFO 命名管道 (IPC) 在特定文件描述符处停止写入/读取消息的主要内容,如果未能解决你的问题,请参考以下文章

IPC - 命名管道(fifo)- 使用

IPC - 命名管道(fifo)- 使用

IPC - 命名管道(fifo)- 使用

Linux IPC之管道和FIFO

什么时候应该使用 fifo 文件/命名管道?

Linux下的进程通信方式(IPC)——管道通信