Black Jack 21
Black Jack 21

Reputation: 339

Ambiguous behaviour of kill system call in C

I have made this program and the output so far doesn't make much sense to me. Can someone please explain what is going on?

void handler1a(int x){
    printf("A\n");
}

int main(){
    signal(SIGUSR1, handler1a);
    int p = fork();
    if(p==0)
    {
        sleep(5);
        printf("L \n");
    }
    else
    {
        kill(0,SIGUSR1);
        kill(0,SIGUSR1);
        kill(0,SIGUSR1);
        //kill(0,SIGUSR1);
        wait(NULL);
    }
}

With 3 kill signals, my output is- 5A and 1L. With 2 kill signals, the output is- 4A and 1L. With 4 kill signals, output is- 6A and 1L. It seems like upto 2 kill signals, both parent and child process are using my custom handler but somehow one of them isn't using the handler or isn't getting the kill signal after receiving the signal it twice already (it would explain why only a single A is printed when I add another kill system call after 2 kill system calls).

Upvotes: 0

Views: 164

Answers (2)

skrtbhtngr
skrtbhtngr

Reputation: 2251

Here kill is called by the parent process P with 0 as its pid value which means that all the processes in its group (P itself, as well as the child C) will get the signal and the same custom signal handler will be used to process it.

If you are sending multiple signals to the process C that are of same type (SIGUSR1 here), they will not be queued because that signal will be blocked until the first one received is handled, and they will be discarded.

Only when the signal handler for C returns, C is ready to process the signal again. This explains why there are fewer "A"s in the output from C's invocation of the handler.

You can see which process has called the handler by adding printf("A %d\n", getpid()) inside the handler.

Upvotes: 1

David Schwartz
David Schwartz

Reputation: 182753

Signals aren't queued. So if you send the same signal to a process multiple times, it may get processed any number of times from 1 to the number of times you sent the signal.

Or, to put it another way, for each combination of process and signal, the signal can be in the signaled state. If you send a signal to a process when that process is already in the signaled state for that signal, nothing happens.

A process cannot have two SIGUSR1 signals pending. Either SIGUSR1 is pending or it isn't.

Upvotes: 4

Related Questions