所以我正在尝试创建接受用户输入的程序(例如50的价格)然后第一个孩子将其传递给第二个,第二个添加10个(价格现在是60),第三个然后是50(价格现在是110) )和4只打印/返回最终价格。我有fork in循环而且我正在创建管道,但价格总是相同的,每个孩子只添加10个。有什么问题或如何解决,以便它能按我的意愿运作。
我的代码:
int main(int argc,char *argv[])
{
int anon_pipe[2];
int n,N=4;
char value_price[100];
if(argc>1)
{
int price=atoi(argv[1]);
printf("%d\n",price);
if(pipe(anon_pipe)==-1){
perror("Error opening pipe");
return -1;
}
for(n = 0; n < N; n++){
switch(fork()){
case -1:
perror("Problem calling fork");
return -1;
case 0:
close(anon_pipe[1]);
read(anon_pipe[0],value_price,100);
price+=10;
sprintf(value_price,"%d \n",price);
printf("Price: %d\n",atoi(value_price));
write(anon_pipe[1],value_price,sizeof(value_price));
_exit(0);
}
}
close(anon_pipe[0]);
sleep(1);
close(anon_pipe[1]);
}
return 0;
}
答案 0 :(得分:1)
你似乎认为分叉会让孩子从程序的开头开始。情况并非如此,当fork()
被调用
例如,请看这里的代码:
read(anon_pipe[0],value_price,100);
price+=10;
sprintf(value_price,"%d \n",price);
printf("Price: %d\n",atoi(value_price));
看到你增加price
的值,但你从未从管道中读取该值。所以所有孩子总是输出+10到他们各自的管道。
答案 1 :(得分:0)
您应该检查函数调用的返回值是否有错误代码。如果你已经完成了,你就会检测到这种呼叫组合产生的错误:
close(anon_pipe[1]);
// ...
write(anon_pipe[1],value_price,sizeof(value_price));
很有可能,你也会发现很多这些电话......
read(anon_pipe[0],value_price,100);
...在没有阅读任何内容的情况下发出文件结尾信号。至少,您需要read()
的返回值来确定放置所需字符串终止符的位置(在将缓冲区用作字符串之前未能放置)。
作为一般规则, 强制性 可以处理read()
和write()
的返回值,因为除了可能性之外error / EOF,这些函数可能执行短数据传输而不是完整传输。返回值告诉您传输了多少字节,确定是否循环以尝试传输更多字节。
此外,您的所有进程都使用相同的管道进行相互通信。你可能会很幸运,但很可能至少有时你最终会出现乱码。你真的应该为每对通信进程(包括父进程)创建一个单独的管道。
此外,请勿使用sleep()
来同步进程。它不能可靠地工作。相反,父级应为其每个子进程wait()
或waitpid()
,但只有在启动它们并执行所有必需的管道端处理之后。等待子进程也会阻止他们在退出后的任何重要时间内保留僵尸。当主进程退出而不是继续进行任何其他工作时,这并不重要,如在这种情况下,但是否则它构成资源泄漏(文件描述符)。你应该养成等待孩子过程的好习惯。
当然,如果你实际上没有写下你想写的数据,那么所有这些都没有实际意义; @SanchkeDellowar在他的回答中解释了你是如何做不到的。