Reputation: 25
First, I create the multiple number of child process using the for loop. Then, I put all of the child process into sleep(by adding infinite sleep block).
void kill_child(int sig);
int main(void){
signal(SIGHUP, kill_child);
for(int i = 0; i < max_child; i++){
pid_t id = fork();
if(id == 0){
printf("Hi, i am a child\n");
while(1){sleep(1);}
}
if(id == 1){
printf("Hi, i am a parent\n");
}
}
}
void kill_child(int sig){
if(sig==SIGHUP){
//do stuff to kill single child
}
}
What am I planning to do next, send the kill -HUP parent from terminal to kill the child process one by one. At the end, if no child process terminate the program.
I just want to know is there any way to kill single child at a time under condition like this.
Upvotes: 0
Views: 1305
Reputation: 12668
From your code:
int main(void){
signal(SIGHUP, kill_child);
for(int i = 0; i < max_child; i++){
pid_t id = fork();
if(id == 0){
printf("Hi, i am a child\n");
while(1){sleep(1);}
}
if(id == 1){
where do you get that id == 1
when fork()
returns to the parent? That's never true. For that you have had to fork()
the init
process, and that's never true for a user process. The kernel returns the pid (and this is why you call it id
) of the child process to the parent, so you never get into the following piece of code.
printf("Hi, i am a parent\n");
}
}
}
You need to arrange an array (as told you in another answer) and save all the pids of all the processes you have forked. Instead of the printf()
above, just do the following.
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#define MAX_CHILDREN 10
pid_t chld_pids[MAX_CHILDREN];
size_t chld_pids_sz = 0;
void kill_children(int sig, int delay);
void signal_handler(int sig);
int main()
{
while (chld_pids_sz < MAX_CHILDREN) {
pid_t chld_id = fork();
if (chld_id < 0) { /* error in fork() */
fprintf(stderr,
"Error in fork: %s (errno == %d)\n",
strerror(errno), errno);
kill_children(SIGHUP, 0); /* kill all children with
* no delay */
break; /* stop processing */
} else if (chld_id == 0) { /* child */
/* avoid signal SIGHUP so no child is killed when the
* process group leader is killed. This is sent
* automatically by the kernel to end a job. */
signal(SIGHUP, SIG_IGN);
for(;;) {
/* print our pid on stdout each second to
* indicate we are alive. */
printf("[%d]", getpid());
fflush(stdout); /* force buffer flush */
sleep(1);
}
/* NOTREACHED */
} else { /* parent */
printf("Parent: started child %d\n", chld_id);
chld_pids[chld_pids_sz++] = chld_id;
}
}
signal(SIGHUP, signal_handler);
/* now we wait for all children to finish, no need to know
* the pids, as we are waiting until wait(2) returns an error
* (no children to wait for) */
int chld_id, status;
while ((chld_id = wait(&status)) >= 0) {
if (WIFEXITED(status)) {
printf("Child %d exited with status %d\n",
chld_id, WEXITSTATUS(status));
} else if (WIFSIGNALED(status)) {
printf("Child %d was killed with signal %d\n",
chld_id, WTERMSIG(status));
if (WCOREDUMP(status)) {
printf("Child %d dumped a core file\n",
chld_id);
}
}
}
} /* main */
void kill_children(int sig, int delay)
{
printf("kill_children: Using delay %d\n", delay);
for (int i = 0; i < chld_pids_sz; ++i) {
if (delay > 0) { /* only sleep if delay > 0 */
sleep(delay);
}
printf("Killing pid=%d\n", chld_pids[i]);
int res = kill(chld_pids[i], sig);
if (res < 0) {
printf("Error killing pid %d: %s (errno = %d)\n",
chld_pids[i], strerror(errno), errno);
}
}
}
void signal_handler(int unused)
{
kill_children(SIGINT, 3);
}
a copy of this code is published here iif you want to download it and follow the versioning of it.
Upvotes: 0
Reputation: 36
I Think you can use an array with global scope to safe children's pid and then use it into the function kill_child calling: int kill(pid_t pid, int sig). Inside kill_child, I think you can send SIGKILL to children or redefine behavior with signal function if you want to send SIGTERM. This can be a solution. Aniway, I noticed something that can be improved (in my humble opinion) in your code:
I hope I have helped you!
Upvotes: 1