4个子进程之间的管道通信仅在第一次工作

时间:2016-12-06 15:43:54

标签: c linux pipe fork

我写了这个程序,它接受了N个参数,并将它们从第一个子进程发送到最后一个。第二个孩子的收入增加了20%,第三个孩子增加了30%。

问题是第一个孩子总是只发送第一个参数。我似乎无法找到这个bug。有人可以帮我解决这个问题吗?以下是输出示例:

./prodajnaVerigaAnon 200 100 50
312 312 312

应该是:312 156 78.
这是代码:

for(int i=1;i<argc;i++) {
     char init_price[size];
     const int len = sprintf(init_price,"%d",atoi(argv[i]));
     write(fd1[1], init_price, (size_t) len + 1);
}
close(fd1[1]);
_exit(0);
编辑:我删除了大部分代码,因为这是一项学校作业。

2 个答案:

答案 0 :(得分:0)

管道是一个数据流。读取次数不一定等于写入次数。

在这种情况下会发生的情况是第一个孩子对管道进行三次写入,然后第二个孩子在一次读取中读取所有三个值。您没有检查read的返回值以查看已读取的字节数。

调用read后,检查返回值以查看读取的字节数。然后使用strtol代替atoi来转换价值。前者允许你传入指针,返回时会指向缓冲区中转换停止的位置。然后,您可以继续从那里读取,直到缓冲区耗尽,然后再次呼叫read

答案 1 :(得分:0)

问题是,

write(fd1[1], init_price, (size_t) len + 1);

写入函数通过管道fd1发送200 [1]但是没有可用的读取器,这就是为什么管道没有机会冲出,管道中仍然存在200。 所以你的管道无法获得更多的输入。

何时

  read(fd1[0], readbuffer, sizeof(readbuffer)); 

可用,它只在管道中找到200,因此只读取该值。

如果你想看到变化然后放入睡眠,你会发现读者也能够读取其他数据。因为睡眠有助于上下文切换。所以读者进程可以监听管道。

for(i=1;i<argc;i++) 
{
     char init_price[size];
     const int len = sprintf(init_price,"%d",atoi(argv[i]));
     write(fd1[1], init_price, (size_t) len + 1);
     sleep(2);
 }
 close(fd1[1]);
 _exit(0);