gpt4 book ai didi

c - 调用 waitpid 后父进程挂起

转载 作者:行者123 更新时间:2023-11-30 14:55:37 31 4
gpt4 key购买 nike

当我在 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;
}

最佳答案

您的问题是,在父级中,您小心地关闭了 myPipe[0],然后神秘地决定写入它,而不是仍然打开的 myPipe[1] 。如果您对系统调用进行了错误检查,您就会知道无法将任何数据发送给 child 。事实上,子进程仍在等待数据到达,并且不会退出,而父进程正在等待不会退出的子进程退出,因此出现了死锁。

我正在使用 stderr.cstderr.h 中的错误报告函数 — 可从 GitHub ( https://github.com/jleffler/soq/tree/master/src/libsoq ) 获取其代码来报告错误(以及进展)。

#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?)

关于c - 调用 waitpid 后父进程挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45703410/

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