gpt4 book ai didi

c - 关闭写入器后从管道读取被阻塞

转载 作者:行者123 更新时间:2023-12-02 01:22:22 25 4
gpt4 key购买 nike

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

int main(int argc, char **argv) {

int childs[3];
for (int i = 0; i < 3; ++i) {
int p[2];
if (pipe(p) == -1) { perror("pipe"); exit(1); }

pid_t pid = fork();
if (pid) {
close(p[0]);
childs[i] = p[1];
}
else {
close(p[1]);
printf("child %d start\n", i + 1);

char buf[10];
buf[0] = 0;
int r;
if ((r = read(p[0], buf, 9)) == -1) { ... }

printf("child %d read %s (%d), finish\n", i + 1, buf, r);

sleep(2);
exit(0);
}
}

for (int i = 0; i < 3; ++i) {
// if (argc > 1) {
// write(childs[i], "42", 2);
// }
// ============== HERE >>>
close(childs[i]);
}

pid_t pid;
while ((pid = waitpid(-1, NULL, 0)) > 0) {
printf("child %d exited\n", pid);
}

return 0;
}

带注释的输出:

child 1 start
child 2 start
child 3 start
child 3 read (0), finish

2秒后显示下一行

child 2 read  (0), finish

2秒后显示下一行

child 1 read  (0), finish

我不写入父 channel 。关闭它,我想给将在 read 中等待的 child 一个信号。

好像有下面的。 Сhild N expected 完成从结果 0 读取,没问题。 child 2 (N-1)1 被锁定在一个 read 到 child 3 完成。然后 child 1 是相似的将等待。

为什么会出现锁?

最佳答案

子进程从父进程继承打开的文件描述符。您的主进程在循环中打开文件描述符(使用 pipe,仅保留写入端)。 child 1 不继承任何描述符(stdin/stdout/stderr 除外); child 2 继承 childs[0](描述符转到 child 1); child 3 继承了 childs[0]childs[1](描述符指向 child 1 和 2)。

只要任何写描述符仍处于打开状态(因为它可用于发送更多数据),管道上的

read 就会阻塞。所以 child 1 等待(因为 child 2 和 child 3 仍然有一个打开的写描述符)并且 child 2 等待(因为 child 3 仍然有一个打开的写描述符);只有 child 3 sleep 并退出。这会导致其文件描述符关闭,从而唤醒 child 2。然后 child 2 休眠并退出,关闭其文件描述符,最终唤醒 child 1。


如果你想避免这种行为,你必须关闭每个 child 中打开的文件描述符:

    else {
for (int j = 0; j < i; j++) {
close(childs[j]);
}
close(p[1]);
printf("child %d start\n", i + 1);

关于c - 关闭写入器后从管道读取被阻塞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39195735/

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