为什么我们会两次调用信号处理程序?

3

我是一个对使用C语言进行信号处理的新手。我正在分析下面从特定资源中提取的信号处理代码。

以下是该代码。

    #include <stdio.h>
    #include <signal.h>

    void intproc();
    void quitproc();

    main()
    {
      int i;

      signal(SIGINT,intproc);
      signal(SIGQUIT,quitproc);

      printf("Ctrl+c is disabled. Use ctrl+\\ to quit\n");

      for (i=0;;i++) {
        printf("In an infinite loop...\n"); 
        sleep(200);
        }
    }


    void intproc()
    {
      signal(SIGINT,intproc);
      printf("You have pressed ctrl+c.\n");
    }

    void quitproc()
    { signal(SIGQUIT,intproc);
      printf("You have pressed ctrl+\\. Now the program quits.\n");
      exit(0);
    }

我想知道为什么我们在intproc()函数内部再次调用信号处理程序"(SIGINT,intproc)"?

我尝试在该函数中不使用该信号处理程序运行此代码,它也可以正常工作。


信号处理不在C标准中,而在Posix标准中。 - Basile Starynkevitch
2个回答

3

这是非常老的代码。在旧时代(可能是SunOS3,1990年代),信号处理程序在执行后会自动卸载。请查看signal(2)(SysV和BSD行为之间的差异),避免使用signal

仔细阅读signal(7),然后使用sigaction(2)。不要使用signal(2)。关注异步信号安全函数(您可以从信号处理程序中调用的唯一函数;您不应在信号处理程序内部使用printf!)。考虑在信号处理程序中简单设置一些volatile sig_atomic_t全局变量(或static)(并在外部进行测试)。

阅读Advanced Linux Programming,其中详细解释了这些内容。


1

在函数intproc完成后,程序继续执行,但信号操作被恢复为默认值。当它接收到第二个SIGINT信号时,程序将采取默认操作,即终止程序。

如果您想保留信号处理程序,您需要通过再次调用signal来重新建立它。

这就是为什么您应该始终优先选择更健壮的sigaction而不是signal函数的原因。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接