FIFO 通道读取不正确

FIFO channel reading incorrect

我有 2 个不相关的进程。第一个创建一个 FIFO 通道并向其中写入数据。

测试补偿:

int main(int argc, char *argv[])
{
    int f1;
    char *send_buf = "Hello";
    char recv_buf[128] = {0};

    if (mkfifo("mk.fifo", S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) == -1 && errno != EEXIST)
        error(0, errno, "mkfifo() error");

    f1 = open("mk.fifo", O_RDWR);
    perror("Opening ");

    printf("Sending string '%s'...\n", send_buf);
    write(f1, send_buf, strlen(send_buf));
    perror("Writing ");

    close(f1);
    return 0;
}

第二个进程应该从之前创建的通道中读取数据。

test2comp:

int main(int argc, char *argv[])
{
    int f2;
    char recv_buf[128] = {0};

    f2 = open("mk.fifo", O_RDONLY|O_NONBLOCK);
    perror("Opening ");

    read(f2, recv_buf, sizeof(recv_buf));
    perror("Reading ");

    printf("Received string '%s'\n", recv_buf);

    close(f2);
    return 0;
}

问题是读取的数据为空。可能是什么原因?

控制台输出:

FIFO 就是一个命名管道。

它必须在两端同时打开才能进行通信。例如,您的本地 man page 应该说

The kernel maintains exactly one pipe object for each FIFO special file that is opened by at least one process. The FIFO must be opened on both ends (reading and writing) before data can be passed. Normally, opening the FIFO blocks until the other end is opened also.

你所做的是:

  1. 创建一个 FIFO inode
  2. 打开它进行写入,隐式创建与该 inode 关联的管道
  3. 向管道缓冲区写入内容,即使尚未从中读取任何内容
  4. 再次关闭它,破坏管道
  5. 打开一个新的管道用于读取,与相同的(当前未使用的)inode 相关联
  6. 里面什么都没有,因为是新管子

通常我希望作者在打开 fifo 时阻塞,直到出现 reader - 我不确定为什么这没有发生。您通过将 reader 设置为非阻塞来明确禁用此行为。