【问题标题】:How to install a signal handler to call a function when 'SIGINT' is received收到“SIGINT”时如何安装信号处理程序以调用函数
【发布时间】:2023-04-02 23:10:01
【问题描述】:

当我收到SIGINT 时,我应该安装一个信号处理程序来调用函数stopContinue()。这是我在 C 中的代码 sn-p,但我不确定这是否正确。请让我知道我哪里出错了。

struct sigaction act;

memset(&act, '\0', sizeof(act));
action.sa_flags = 0; 
action.sa_handler = stopContinue;
sigaction(SIGINT, &act, NULL);

这看起来大致正确吗?

有一个关于使用sigaction vs. action的讨论,这里使用标志与另一个问题不同,这不是一个骗局。

【问题讨论】:

  • 当你尝试运行它时发生了什么?
  • Catch Ctrl-C in C的可能重复
  • 您还需要清除阻塞信号集,例如使用sigemptyset(&act.sa_mask);memset() 之后。
  • 你没有检查代码当前是否忽略中断;如果是,您可能不应该重新启用中断处理。这是一个标准问题。使用sigaction(),您可以使用sigaction(SIGINT, NULL, &act) 来查找当前的信号处理状态——然后您可以修改它并或多或少地设置一个新状态,如图所示。

标签: c signals


【解决方案1】:

如果您甚至不打算使用结构的sa_flags 成员,为什么还要使用sigaction?要在按下 Ctrl+C 时调用stopContinue,您可以使用:

signal(SIGINT, stopContinue);

如果你只是想忽略 Ctrl+C,你可以让它更简单:

signal(SIGINT, SIG_IGN);

SIG_IGNmacro 以忽略信号。

【讨论】:

  • 因为signal() 仅在与SIG_DFLSIG_IGN 一起使用时才可移植,而sigaction() 是此处使用的正确POSIX.1 标准函数,因此您的建议很糟糕。
  • @NominalAnimal POSIX 并不完全是可移植的,但是...... 没关系。不是我的意思。
  • 别开玩笑了。 POSIX 语义用于 Linux、BSD、macOS、Solaris、Tru64 等等——基本上除了 Windows 之外的所有地方。像这样的 Windows 东西和愚蠢的建议是不可移植的。
  • @NominalAnimal signal 的行为在 POSIX 中是否有足够的差异,以至于在两个不同的平台上编写 signal(SIGNAL, FUNCTION)在收到 SIGNAL 时可能不会调用 FUNCTION
  • 在 SysV Unix 机器上,FUNCTION 只会在第一个信号传递时调用,而在第二个信号传递时会重置配置;这意味着两个 Ctrl+C 快速连续通常会终止该进程。 BSD signal() 安装处理程序就好像 .sa_flags = SA_RESTART 是通过 sigaction 指定的,因此传递不会中断阻塞的系统调用。由于信号处理程序通常只设置一个volatile sig_atomic_t 标志,并且依赖于中断主处理循环以便检查标志,因此这不会在 BSD 上发生。
猜你喜欢
  • 2013-12-21
  • 2016-07-12
  • 1970-01-01
  • 2011-08-15
  • 1970-01-01
  • 1970-01-01
  • 2022-06-14
  • 2014-02-06
  • 1970-01-01
相关资源
最近更新 更多