Signal Processing in C

I understand how signals work in C. Here is one example taken from old exams:

#include<signal.h> #include<unistd.h> #include<stdio.h> #include<errno.h> //#include <sys/types.h> void handler1(int sig) { printf("Phantom"); exit(0); } int main() { pid_t pid1; signal(SIGUSR1, handler1); //installing signal handler if((pid1 = fork()) == 0) { //forking printf("Ghost"); exit(0); } kill(pid1, SIGUSR1); printf("Ninja"); return 0; } 

So far, GCC is giving me two answers Ghost Ninja and Ninja Phantom . Can he create a Ghost Phantom Ninja or any other combination of 3 names?

As I see it, this can lead to 3 names: Plug, start in Child, type Ghost , exit (0) => in Parent, receive / process the signal and print the Phantom signal handler, kill the child, type Ninja . But I'm not sure if my "theory" supports the foundation.

Also, kill(pid1, SIGUSR1) calls handler() ?

Thanks!

+4
source share
4 answers

Let's look at this line by line. Set up the signal handler, then the plug. The child types "Ghost" and exits. The parent forces the child to type "Phantom" and exit. Then the parent types β€œninja”.

So, you really have a race condition. If the parent launches his SIGUSR1 before the child prints "Ghost", you will get Phantom Ninja or, possibly, Ninja Phantom (kills the block?)

But, if you cannot turn off the signal in time, you will receive the Ghost Ninja when the child finishes before the parent signals. I do not think the opposite is possible.

Now we can assume that the signal may be just in time to get between printf and exit , in which case Ghost will end, then Phantom , then Ninja - or vice versa again, I think.

It is really thin and sensitive to OS synchronization.

@ Total - not verified! Feel free to contradict me, but I will be interested to know why as an OP.

+5
source

Allows you to first mark lines with line numbers as follows:

 signal(SIGUSR1, handler1); //installing signal handler ---- 1 if((pid1 = fork()) == 0) { //forking ---- 2 printf("Ghost"); ---- 3 exit(0); ---- 4 } kill(pid1, SIGUSR1); ---- 5 printf("Ninja"); ---- 6 

Now with the code above, if the Child is executing first and if 3 is executing first, then the child will pause and the parent will start executing with 5. This will print GhostPhantomNinja

However, a specific order cannot be determined.

+1
source

Here you have two non-deterministic factors that both depend on the OS: when will the context switch happen and when will the signal come.

Since you cannot manage them, I would answer that any order is possible. Try inserting wait () between the command and see if you get the desired results.

0
source
 //#include <sys/types.h> #include<stdlib.h> void handler1(int sig) { printf("Phantom\n"); waitpid(-1,NULL,0); //sexit(0); } int main() { pid_t pid1; signal(SIGUSR1, handler1); //installing signal handler printf("my pid is %d ha ha parent..\n",getpid()); //if((pid1 = fork()) == 0) { //forking pid1=fork(); if(pid1==0)//in childe processs { printf("my pid is %d ha ha child..\n",getpid()); printf("Ghost\n"); sleep(6); exit(0); } else{ //sleep(4); kill(pid1, SIGUSR1); sleep(3); printf("Ninja\n"); return 0; } } 
0
source

Source: https://habr.com/ru/post/1332322/


All Articles