当我在gdb中运行它时,父级挂起在waitpid,我不知道为什么。父母应该从argv获取参数并通过管道将它们发送给孩子。那么父母应该通过它的回报从孩子那里得到论据的总和。不知道为什么要这样做。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/poll.h>
static int myPipe[2];
int main(int argc, char **argv)
{
pid_t pid;
int value;
int status;
// set up pipe
if(pipe(myPipe))
{
printf("pipe error\n");
return -1;
}
// call fork()
printf("CS201 - Assignment 3 Premium - I. Forgot\n");
pid = fork();
if (pid == 0) {
// -- running in child process --
int sum = 0;
close(myPipe[1]);
for(int i = argc; i > 1; i--)
{
read(myPipe[0], &value, sizeof(value));
sum += value;
}
// Return sum of numbers.
return sum;
}
else {
// -- running in parent process --
int sum = 0;
close(myPipe[0]);
for(int i = argc; i > 1; i--)
{
value = atoi(argv[i-1]);
write(myPipe[0], &value, sizeof(value));
}
waitpid(pid, &status, 0);
sum = status;
printf("sum = %d\n", sum);
return 0;
}
答案 0 :(得分:1)
你的问题是,在父母中,你小心地关闭myPipe[0]
,然后神秘地决定写信给它而不是仍然打开myPipe[1]
。如果您错误地检查了系统调用,则表示您未能向孩子发送任何数据。实际上,孩子仍然在等待数据到达,并且不会退出,并且父母正在等待不会退出的孩子退出,所以你有一个死锁。
我正在使用stderr.c
和stderr.h
中的错误报告功能 - GitHub(https://github.com/jleffler/soq/tree/master/src/libsoq)提供的代码可以报告错误(和进度)。< / p>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include "stderr.h"
static int myPipe[2];
int main(int argc, char **argv)
{
pid_t pid;
int value;
int status;
err_setarg0(argv[0]);
err_setlogopts(ERR_PID|ERR_MICRO);
if (pipe(myPipe) != 0)
err_syserr("pipe failed: ");
// call fork()
printf("CS201 - Assignment 3 Premium - I. Forgot\n");
pid = fork();
if (pid < 0)
err_syserr("fork failed: ");
else if (pid == 0)
{
// -- running in child process --
int sum = 0;
if (close(myPipe[1]) != 0)
err_syserr("failed to close write end of pipe in child: ");
for (int i = argc; i > 1; i--)
{
if (read(myPipe[0], &value, sizeof(value)) != sizeof(value))
err_syserr("failed to read from parent: ");
sum += value;
}
if (close(myPipe[0]) != 0)
err_syserr("failed to close read end of pipe in child: ");
err_remark("Exiting: sum = %d\n", sum);
return sum;
}
else
{
// -- running in parent process --
int sum = 0;
close(myPipe[0]);
for (int i = argc; i > 1; i--)
{
value = atoi(argv[i - 1]);
err_remark("Writing: %d\n", value);
if (write(myPipe[1], &value, sizeof(value)) != sizeof(value))
err_syserr("failed to write to child: ");
}
if (waitpid(pid, &status, 0) != pid)
err_syserr("failed to wait for child %d: ", pid);
sum = status;
printf("sum = %d\n", sum);
if (WIFEXITED(status))
printf("exit status: %d\n", WEXITSTATUS(status));
return 0;
}
}
示例输出(fp71.c
中的源代码,程序fp71
):
$ gcc -O3 -g -I./inc -std=c11 -Wall -Wextra -Werror -Wmissing-prototypes \
> -Wstrict-prototypes fp71.c -o fp71 -L./lib -lsoq
$ fp71 1 2 4 7
CS201 - Assignment 3 Premium - I. Forgot
fp71: 2017-08-15 20:11:48.453688 - pid=86097: Writing: 7
fp71: 2017-08-15 20:11:48.454267 - pid=86097: Writing: 4
fp71: 2017-08-15 20:11:48.454275 - pid=86097: Writing: 2
fp71: 2017-08-15 20:11:48.454281 - pid=86097: Writing: 1
fp71: 2017-08-15 20:11:48.454348 - pid=86098: Exiting: sum = 14
sum = 3584
exit status: 14
$
十进制值3584对应于十六进制0x0E00。如果你使用WIFEXITED()
和WEXITSTATUS
对其进行分析,则相当于14
,正如您所期望的那样。 (另见Exit values bigger than 255 — possible?)