KennyYang
KennyYang

Reputation: 235

kill() usage confusion in C

I have read the manual of kill, and I know that it is a system call for sending a signal. I write a simple multi process code, each child process will do the handler function if it catch a specified signal, which is SIGUSR1 in my code.

In my code, I have made 3 processes, each process will print out "yo" if they catch SIGUSR1 signal, but the output only print out one time or two time..? That really confuse me, thanks for your help!

Here is my code:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <time.h>
#include <signal.h>
#include <sys/time.h>
#include <string.h>
#define N 3 
int pid_id[N];

void handler (int signum)
{
    printf("yo\n");
}

void child(int process_index)
{
    struct sigaction sa;

    /* Register */
    memset(&sa, 0, sizeof(sa));
    sa.sa_handler = handler;
    sigaction(SIGUSR1, &sa, NULL);

    printf("I am %d.\n", getpid());
    pid_id[process_index] = getpid();
    sleep(5);

    exit(0);
}

int main()
{
    int i, status;
    pid_t pid[N];
    pid_t pid_wait;

    for (i=0;i<N;i++)
    {
        pid[i] = fork();
        if (pid[i]==0)
        {
            child(i);
        }
    }


    for (i=0;i<N;i++)
        kill(pid_id[i], SIGUSR1);

    for (i=0;i<N;i++)
    {
        do
        {
            pid_wait = waitpid(pid[i], &status, WNOHANG);
        }while(pid_wait != pid[i]);

    }
    printf("all done\n");

    return 0;
}

Upvotes: 1

Views: 129

Answers (1)

paddy
paddy

Reputation: 63471

Remember that you're dealing with multiple processes now. Just because in the code it looks like you ran child before kill doesn't mean that it happened in that order. The order of execution is entirely dependent on how the OS schedules CPU time for these processes.

What's happening is that some of the child processes are killed before they can install their signal handler. This is an example of a race condition, much like the sort you get when starting new threads.

This can be solved by synchronising the parent with its children, so that it doesn't continue until all children have notified back that they have completed their necessary initialisation steps.

Upvotes: 2

Related Questions