C

时间:2015-10-24 16:26:50

标签: c unix concurrency

是否可以确保C中的信号调用顺序?我们来看看以下代码:

//main.c
int counter;
pid_t pid;

void alrm_handler(int s)
{
    kill(pid, SIGUSR1);
    alarm(1);
    --counter;
    if (counter == 0)
        kill(pid, SIGTERM);
    printf("%d\n", counter);
    fflush(stdout);
}

int main(int argc, char* argv[])
{
    counter = atoi(argv[1]);
    signal(SIGALRM, alrm_handler);
    alarm(1);

    pid = fork();
    if (!pid)
        execl("child", "child", NULL);

    wait(NULL);

    return 0;
}

//child.c
void usr1_handler(int s)
{
    puts("TEXT");
    fflush(stdout);
}

int main()
{
    signal(SIGUSR1, usr1_handler);

    while(1)
    {
        struct timespec T;
        T.tv_nsec = 100;
        T.tv_sec = 0;
        nanosleep(&T, NULL);
    }

    return 0;
}

即使我发送SIG_USR1 3次,我只得到输出2次。似乎SIGTERM具有更高的优先级或其他东西。在这种情况下如何实现3个输出?

2 个答案:

答案 0 :(得分:4)

示例程序的一个问题是,您将在信号处理程序中使用缓冲I / O,这会影响输出顺序。除了不安全之外,操作不一定按照您期望的顺序完成。

有关讨论,请参阅

答案 1 :(得分:2)

公开集团基本规格问题6 IEEE Std 1003.1,2004版:

  

多个同时挂起信号的顺序   SIGRTMIN到SIGRTMAX的范围被传送到或接受   过程未指定。

您的父进程运行得如此之快,以至于它可能会在子进程收到之前发送SIGUSR1SIGTERM,因此该子进程有两个未决信号且未指定顺序(读取实现已定义 - - 任何订单都可以。)