How to send a signal to another process
Attribution: I thank Jerry Cain at Stanford for inspiring the following content
static void reapChild(int unused) {
while(true) {
pid_t pid = waitpid(-1, NULL, WNOHANG); // don’t wait for all children to return
if(pid <= 0) break: // return 0 means their are still children that haven’t finished
// return -1 means all children have finished
// return of a positive int would mean we got a legitimate pid from a child that finished
// so, we remove the child process from the queue of jobs
printf( “Job %d removed from job list \n”, pid);
}
int main() {
signal(SIGCHLD, reapChild);
for(int i = 0; i < 3; i++) {
pid_t pid = fork();
if(pid == 0) {
char*argv[] = {“date”, NULL};
execvp(argv[0], argv);
}
sleep(1);
printf(“Job %d added to job list\n”, pid);
}
return 0;
}
Problem: Above code prints “Job …removed…” before “Job …added…”.
Background: Think of the printf that adds a job to a job list as a placeholder for some more substantial code. We need to register an interest in hearing about SIGCHILD, but we need to defer acting on the SIGCHLD alert until we are at a place in the code that accomplishes our goal, namely once we have added the job to the job list.
Solution: Use signal blocking to TEMPORARILY suspend acting on the SIGCHLD.
int main() {
signal(SIGCHLD, reapChild);
// prepare a data structure to catalog all of the signals we are paying attention to
// but we want to suspend our obligation to react to until its convenient for us.
sigset_t mask; // gives a 32 bit bit vector o for no signal, 1 for that signal is on
sigemptyset(&mask);
sigaddset(&mask, SIGCHLD);
for(int i = 0; i < 3; i++) {
// still send the SIGCHLD, but suspend having to react to it
sigprocmask(SIG_BLOCK, &mask, NULL);
pid_t pid = fork();
if(pid == 0) {
// don’t block signals behind the child’s back
// this entire solution scaffolding was for the parent to make progress to a certain // point in the code, so lift the block for the child
sigprocmask(SIG_UNBLOCK, &mask, NULL);
char*argv[] = {“date”, NULL};
execvp(argv[0], argv);
}
sleep(1);
printf(“Job %d added to job list\n”, pid);
// back to normal mode where main will call reapChild to react to pending SIGCHLD
sigprocmask(SIG_UNBLOCK, &mask, NULL);
}
return 0;
}
End of example
How to programmatically send a signal to a process to another process.
void kill(pid_t pid, int sig) ;
kill is bad name. It was originally intended to kill the receiving process but was later multi-purposed to just send signals to processes in the family. Now to kill a process use:
kill(pid, 9) where kill is just sending to the process and its the 9 flag that is killing the process. The receiving process cannot install a handler to deal with the -9 flag.
Sorry, the comment form is closed at this time.