【问题标题】:Why we call Signal Handler twice?为什么我们两次调用 Signal Handler?
【发布时间】:2023-03-24 10:14:02
【问题描述】:

我是使用 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() 函数中再次调用 Signal handler "(SIGINT,intproc)" ?

我尝试在该函数中不使用该信号处理程序的情况下运行此代码,并且它也可以工作。

【问题讨论】:

  • 信号处理不在 C 标准中,而是在 Posix 标准中。

标签: c linux signals signal-processing


【解决方案1】:

这是非常古老的代码。在过去(可能是 SunOS3,1990-s),信号处理程序在执行时会自动卸载。请参阅signal(2)(SysV 和 BSD 行为之间的差异)并避免使用signal

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

阅读Advanced Linux Programming,它详细解释了这些事情。

【讨论】:

    【解决方案2】:

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

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

    这就是为什么你应该总是更喜欢sigaction 而不是signal 函数。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-04-03
      • 1970-01-01
      • 1970-01-01
      • 2017-12-06
      • 1970-01-01
      • 2021-08-02
      • 1970-01-01
      • 2019-08-07
      相关资源
      最近更新 更多