开发者

sending signal to child processes got lost for some reason. sleep function change result in a strange way

开发者 https://www.devze.com 2023-04-04 17:06 出处:网络
Im a beginner C dev. I开发者_如何学编程m trying to understand in what way C manages kills, signals and sleep. See:

Im a beginner C dev. I开发者_如何学编程m trying to understand in what way C manages kills, signals and sleep. See:

void son1_handler(int sig)
{
    printf("[SON1]:");
    fflush(stdout);
}

void son2_handler(int sig)
{
    printf("[SON2]:");
    fflush(stdout);
}

int main(int argc, char **argv)
{
    pid_t son1, son2;
    son1 = fork();
    if (son1 == 0)
    {
        while (1)
        {
            signal(SIGUSR1, son1_handler);
        };
    }

    son2 = fork();
    if (son2 == 0)
    {
        while (1)
        {
            signal(SIGUSR2, son2_handler);
        };
    }

    while (1)
    {
        sleep(1);
        kill(son1, SIGUSR1);
        kill(son2, SIGUSR2);
    }
}

My objective is to print: [SON1]:[SON2]:[SON1]:[SON2].... With code above, sometimes got that, sometimes [SON2]:[SON1]:[SON2]...

I thought changing using sleep between kills:

kill(son1, SIGUSR1);
sleep(1);
kill(son2, SIGUSR2);

but surprisingly the result was: [SON2]:[SON2]:[SON2]:[SON2]:[SON2]....

I think that i must be misunderstangding something about sleep, kill, or signal. Do you have any ideas? Really thanks in advance.


This is because of process scheduling.

When you 'send' a signal, the corresponding bit in the PCB (Process Control Block) is set. and then when the process to which the signal was sent is scheduled, it checks for signals and runs the handlers.

In your above example, parent process is sending the signals one after another but there is no guarantee that 'son1' will be executed before 'son2'.

Sleep just allows the operating system to 'switch the context' i.e. allow other program to run. So, in this case

kill(son1, SIGUSR1);
sleep(1);
kill(son2, SIGUSR2);

You send a signal to son1 and then put parent process to sleep. However, it is not necessary that son1 process will be scheduled before parent process again. This depends on the operating system's process scheduler. You would need to use some sort of mutex mechanism like semaphores if you want to achieve synchronization like you mentioned.

Hope that clears things up.

Edit: Also, in Linux, the signal handlers stay registered even after subsequent calls to them unlike in Unix where signal handlers get unregistered after one call. This means you only have to call signal() once in your child programs instead of calling in every iteration of your while() loops.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号