gpt4 book ai didi

c - unlink() 后从 FIFO 读取

转载 作者:太空狗 更新时间:2023-10-29 15:07:59 26 4
gpt4 key购买 nike

我创建了一个 FIFO,写入并取消链接。令我惊讶的是,我在取消链接后能够从 fifo 读取数据,这是为什么?

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

#define MAX_BUF 256
int main()
{
int fd;
char * myfifo = "/tmp/myfifo";

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

int pid = fork();
if (pid != 0)
{
/* write "Hi" to the FIFO */
fd = open(myfifo, O_WRONLY);
write(fd, "Hi", sizeof("Hi"));
close(fd);

/* remove the FIFO */
unlink(myfifo);
}
else
{
wait(NULL);
char buf[MAX_BUF];

/* open, read, and display the message from the FIFO */
fd = open(myfifo, O_RDONLY);
read(fd, buf, MAX_BUF);
printf("Received: %s\n", buf);
close(fd);

return 0;
}


return 0;
}

最佳答案

除非您将 O_NONBLOCK 标志传递给 open(2),否则打开一个 FIFO block 直到打开另一端。来自 man 7 fifo:

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.

A process can open a FIFO in nonblocking mode. In this case, opening for read only will succeed even if no-one has opened on the write side yet, opening for write only will fail with ENXIO (no such device or address) unless the other end has already been opened.

也就是说,您的父/子进程在打开 FIFO 时隐式同步。所以当父进程调用 unlink(2) 时,子进程早就打开了 FIFO。因此, child 总是找到 FIFO 对象并在父对其调用 unlink(2) 之前打开它。

关于 unlink(2) 的注释:unlink(2) 只是从文件系统中删除文件名;只要至少有一个进程打开了文件(在本例中为 FIFO),底层对象就会持续存在。只有在该进程终止或关闭文件描述符后,操作系统才会释放相关资源。 FWIW,这与这个问题的范围无关,但似乎值得注意。

其他一些(不相关的)评论:

  • 不要对 child 调用wait(2)。它会返回一个错误(你立即忽略),因为 child 没有 fork 任何进程。
  • mkfifo(3), fork(2), open(2), read(2) , write(2), close(2)unlink(2) 都可能失败并返回 -1 .您应该优雅地处理可能的错误,而不是忽略它们。这些玩具程序的常见策略是使用 perror(3) 打印描述性错误消息并终止。
  • 如果你只想父子之间的通信,使用管道:它更容易设置,你不需要取消链接,它不会暴露在文件系统中(但你需要用 pipe 创建它(2)在fork之前,让 child 可以访问)。

关于c - unlink() 后从 FIFO 读取,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32287079/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com