问题
I'm very new to c and programming and need some help. In c on linux(cygwin) I am required to remove all child processes at exit. I have looked at the other similar questions but can't get it to work. I've tried-
atexit(killzombies); //in parent process
void killzombies(void)
{
printf("works");
kill(0, SIGTERM);
printf("works");
if (waitpid(-1, SIGCHLD, WNOHANG) < 0)
printf("works");
}
for some reason, "works" doesn't even print ever. I press ctrl + c to exit.
ALSO I have tried-
prctl(PR_SET_PDEATHSIG, SIGHUP); //in child process
signal(SIGHUP, killMe);
void killMe()
{
printf("works");
exit(1);
}
but because I'm using cygwin, when I #include <sys/prctl.h>
, cygwin says it can't find the file or directory and I don't know what package to install for it.
Also, if my prctl()
function were to work, would that kill all the zombies?
My program is a client server and my server forks() to handle each client. I'm suppose to leave no remaining zombies when the server shuts down.
回答1:
From the Linux documentation of atexit(3)
:
Functions registered using
atexit()
(andon_exit(3)
) are not called if a process terminates abnormally because of the delivery of a signal.
If you want to cleanup when your application receives a SIGINT or SIGTERM, you'll need to install the appropriate signal handlers and do your work there.
回答2:
Your waitpid
does not supply the usual parameters, I'm surprised it does not crash. The prototype is:
pid_t waitpid(pid_t pid, int *status, int options);
The second parameter should be a pointer to an int
, you are supplying an int
.
Notice also that you should call waitpid
for each child, you are only calling it for one.
atexit()
is only called if you exit normally. If you are exiting through CTRL+C then you need to call your function from a handler on SIGINT.
回答3:
You'll need to keep track of how many children your process has and then call wait that many times. Also, as others have said, your atexit() function won't be called if the process is terminated by a signal, so you'll need to call killzombies() from a signal handler as well. You'll need something like:
int n_children = 0; // global
void handle_sig(int sig) {
killzombies();
exit(sig);
}
// your atexit()
void killzombies() {
kill(0, SIGKILL);
while (n_children > 0) {
if (wait(NULL) != -1) {
n_children--;
}
}
}
来源:https://stackoverflow.com/questions/12427524/killing-child-processes-at-parent-process-exit