pipe from child to parent: the parent exits, but the child does not
From: Alexander Farber (Alexander.Farber_at_gmail.com)
Date: 08/24/05
- Next message: Maxim Yegorushkin: "Re: kernel timer"
- Previous message: martinm69x_at_hotmail.com: "Re: kernel timer"
- Next in thread: Alexander Farber: "Re: pipe from child to parent: the parent exits, but the child does not"
- Reply: Alexander Farber: "Re: pipe from child to parent: the parent exits, but the child does not"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Date: 24 Aug 2005 02:31:55 -0700
Hi,
BACKGROUND (and the simple test case program is on the bottom):
I'm programming a load-balancer, which keeps fetching average
load values (similar to the rup command) from a list machines:
status = clnt_call(rstat_clnt, RSTATPROC_STATS,
(xdrproc_t) xdr_void, NULL,
(xdrproc_t) xdr_statstime, (char *) &stats,
timeout);
....
Because the clnt_call() blocks, I go through my list of machines,
create a pipe for each of them and fork a child, which calls that
function in a loop. Each child write()s then the 3 fetched int values
(ok, they are long on HP) via the pipe to the parent. And the parent
poll()s the reading ends of the pipes (which I also set nonblocking).
MY PROBLEM: is that when the parent exit()s, then the children don't
notice that the reading end of pipe is closed and keep running.
I understand, that as a workaround I could save the children pids
into my list of machines and - before exiting the parent -
go through that list and send a signal to each child.
But I was actually hoping, that the children would notice that event
also without a signal, since in the Stevens' Unix-Prg. book Ch. 15.2
he writes that when the SIGPIPE is ignored and the reading end of a
pipe closes, then the writing part gets -1 and errno = EPIPE.
So I have prepared a simple test case program, which forks NKIDS
number of children, who then keep writing to the parent. The parent
however sleeps 10 seconds and exits.
Now the strangs part is that for NKIDS = 1 I get the expected
behaviour - the single child gets -1 and EPIPE and exits:
bolinux72:/home/afarber> ./kids-pipe
written kid0, n = 5
written kid0, n = 5
written kid0, n = 5
written kid0, n = 5
written kid0, n = 5
written kid0, n = 5
written kid0, n = 5
written kid0, n = 5
written kid0, n = 5
written kid0, n = 5
bolinux72:/home/afarber> n = -1, errno = Broken pipe
But for NKIDS = 2 the children don't exit for some reason.
bolinux72:/home/afarber> ./kids-pipe
written kid0, n = 5
written kid1, n = 5
written kid0, n = 5
written kid1, n = 5
....keeps going....
Since I have the same behaviour on OpenBSD 3.7 stable, RedHat Linux 9
and HP-UX 11.11, I'm probably missing something very obvious... ?
Regards
Alex
PS: And here is my test program (please change NKIDS there):
bolinux72:/home/afarber> cat kids-pipe.c
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include <stdio.h>
#include <sys/types.h>
extern char *__progname;
#define NKIDS 2
#define NAMELEN 5
struct kid_s {
int pipefd[2];
char name[NAMELEN];
} kids[NKIDS];
void
die(const char *s)
{
perror(s);
exit(1);
}
int
main(int argc, char *argv[])
{
int i, n;
pid_t pid;
struct kid_s *pkid;
if (signal(SIGPIPE, SIG_IGN) < 0)
die("signal error");
for (i = 0; i < NKIDS; i++) {
pkid = &kids[i];
snprintf(pkid->name, NAMELEN, "kid%d\n", i);
if (pipe(pkid->pipefd) == -1)
die("pipe error");
}
for (i = 0; i < NKIDS; i++) {
pkid = &kids[i];
switch(pid = fork()) {
case -1:
die("fork error");
/* child, keep writing to parent */
case 0:
close(pkid->pipefd[0]);
while(1) {
n = write(pkid->pipefd[1],
pkid->name, NAMELEN);
if (n != NAMELEN) {
fprintf(stderr,
"n = %d, errno = %s\n",
n, strerror(errno));
break;
}
fprintf(stderr, "written %s, n = %d\n",
pkid->name, n);
sleep(1);
}
_exit(0);
/* parent, sleep and exit */
default:
close(pkid->pipefd[1]);
}
}
sleep(10);
exit(0);
}
- Next message: Maxim Yegorushkin: "Re: kernel timer"
- Previous message: martinm69x_at_hotmail.com: "Re: kernel timer"
- Next in thread: Alexander Farber: "Re: pipe from child to parent: the parent exits, but the child does not"
- Reply: Alexander Farber: "Re: pipe from child to parent: the parent exits, but the child does not"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Relevant Pages
|