信号处理程序显示C中的混淆

时间:2015-12-16 11:58:52

标签: c multiprocessing signals

我正在尝试使用信号同步N个进程然后打印出一些东西。 每个子进程注册一个处理程序,在捕获SIGUSR1时打印“yo”和“hihi”。 我使用kill(0,SIGUSR1)来触发每个进程。由于捕获SIGUSR1的默认操作被杀死,我为主进程设置了一个do-nothing处理程序,以便它等待所有孩子死亡。

fork和发送信号程序将重复k次,我预计它将显示N * k次“yo”和“hihi”。但是,它没有像我期望的那样显示出足够的“哟”和“hihi”。每次执行时“哟”的数量都不同。

这是我的代码,感谢您的帮助!

    #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 handler2 (int signum)
    {
        printf("hihi\n");
    }

    void handler (int signum)
    {
        signal(SIGUSR2, handler2); 
        printf("yo\n");
        raise(SIGUSR2);
    }

    void handler_do_nothing (int signum)
    {
        ;
    }

    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(1);

        exit(0);
    }

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

        struct sigaction sa_main;

        /* Register */    /* Main process will terminate if catch SIGUSR1 by default setting*/ 
        memset(&sa_main, 0, sizeof(sa_main));
        sa_main.sa_handler = handler_do_nothing;
        sigaction(SIGUSR1, &sa_main, NULL);

        /* Race k times */
        for (k=0;k<3;k++) 
        {

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

             // sleep();
             kill(0, SIGUSR1);

            for (i=0;i<N;i++)
            {
                do
                {
                    pid_wait = waitpid(pid[i], &status, WNOHANG);
                    printf("I am waiting..\n");
                    sleep(1);
                }while(pid_wait != pid[i]);
            }
        }
        printf("all done\n");

        return 0;
    }

1 个答案:

答案 0 :(得分:1)

您的子进程在有时间(即已安排执行资源)安装新信号处理程序之前就会发出信号。

这意味着当主程序发送SIGUSR1时,子进程的某些子集仍将安装handler_do_nothing

如果要等到子进程完成所有设置,则需要添加一些进程间通信机制 - 例如孩子们准备好后可以向父母发出信号。