gpt4 book ai didi

c - 为什么我的写入没有阻塞到这个管道?

转载 作者:太空狗 更新时间:2023-10-29 12:23:13 25 4
gpt4 key购买 nike

我正在编写一个小的 Linux fifo 测试程序。

我使用 mkfifo mpipe 创建了一个管道。该程序应该为每个发送给它的参数执行一次写入。如果未发送任何参数,则它会从管道中执行一次读取。

这是我的代码

int main(int argc, char *argv[])
{
if (argc > 1)
{
int fd = open("./mpipe", O_WRONLY);
int i = 1;
for (i; i < argc; i++)
{
int bytes = write(fd, argv[i], strlen(argv[i]) + 1);
if (bytes <= 0)
{
printf("ERROR: write\n");
close(fd);
return 1;
}
printf("Wrote %d bytes: %s\n", bytes, argv[i]);
}

close(fd);
return 0;
}

/* Else perform one read */
char buf[64];
int bytes = 0;

int fd = open("./mpipe", O_RDONLY);
bytes = read(fd, buf, 64);
if (bytes <= 0)
{
printf("ERROR: read\n");
close(fd);
return 1;
}
else
{
printf("Read %d bytes: %s\n", bytes, buf);
}

close(fd);
return 0;
}

我希望行为是这样的......

我调用 ./pt 你好,我是最深的人,我希望它会阻塞 6 次读取。相反,一次读取似乎足以触发多次写入。我的输出看起来像

# Term 1 - writer
$: ./pt hello i am the deepest guy # this call blocks until a read, but then cascades.
Just wrote hello
Just wrote i
Just wrote am
Just wrote the # output ends here

# Term 2 - reader
$: ./pt
Read 6 bytes: hello

有人可以帮助解释这种奇怪的行为吗?我认为就管道通信而言,每次读取都必须与写入相匹配。

最佳答案

那里发生的事情是,内核在 open(2) 系统调用中阻止写入进程,直到您有一个读取器打开它进行读取。 (fifo 要求两端都连接到进程才能工作)一旦读取器执行第一个 read(2) 调用(写入器或读取器阻塞,谁先进行系统调用)内核通过从写入器到读取器的所有数据,并唤醒两个进程(这就是只接收第一个命令行参数而不是写入器的前 16 个字节的原因,你只得到六个字符 {'h' , 'e', 'l', 'l', 'o', '\0' 来自阻塞编写器)

最后,当读取器刚刚关闭 fifo 时,写入器被 SIGPIPE 信号杀死,因为没有更多的读取器打开 fifo。如果您在写入进程上安装信号处理程序(或忽略该信号),您将从 write(2) 系统调用中得到一个错误,告诉您 fifo 上没有更多的读取器被阻塞(EPIPE errno value) on the blocking write.

请注意,这是一个功能,而不是一个错误,一种知道在您关闭并重新打开 fifo 之前写入不会到达任何读者的方法。

内核会为整个 read(2)write(2) 调用阻塞 fifo 的 inode ,因此即使另一个进程执行另一个 write( 2) fifo 上的 将被阻止,您将无法从第二个写入器(如果有的话)那里获得读取器上的数据。如果愿意,您可以尝试启动两个编写器,看看会发生什么。

$ pru I am the best &
[1] 271
$ pru
Read 2 bytes: I
Wrote 2 bytes: I
Wrote 3 bytes: am
[1]+ Broken pipe pru I am the best <<< this is the kill to the writer process, announced by the shell.
$ _

关于c - 为什么我的写入没有阻塞到这个管道?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50730214/

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