Sie Problem ist, dass in der übergeordneten, Sie sorgfältig schließen myPipe[0]
und dann auf mysteriöse Weise, um es anstelle des noch offenen myPipe[1]
zu schreiben entscheiden. Wenn Sie bei Ihren Systemaufrufen einen Fehler festgestellt haben, wissen Sie, dass Sie keine Daten an das untergeordnete System gesendet haben. So wie es ist, wartet das Kind immer noch darauf, dass die Daten ankommen, und wird nicht beendet, und das Elternteil wartet auf das Kind, das nicht zum Ausgang gehen wird, so dass Sie einen Deadlock haben.
Ich verwende die Fehler Reporting-Funktionen von stderr.c
und stderr.h
- der Code für die von GitHub verfügbar ist (https://github.com/jleffler/soq/tree/master/src/libsoq) Fehler zu melden (und Fortschritt).
#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;
}
}
Und Beispielausgabe (Quellcode in fp71.c
, Programm 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
$
Der Dezimalwert 3584 entspricht 0x0E00 auf hexadezimal. Wenn Sie das mit WIFEXITED()
und WEXITSTATUS
analzye, dann entspricht das 14
, wie Sie erwarten würden. (Siehe auch Exit values bigger than 255 — possible?)