【问题标题】:Pass local variable to a signal handler function [duplicate]将局部变量传递给信号处理函数[重复]
【发布时间】:2020-11-06 10:45:09
【问题描述】:

我想将一些数据的副本发送到信号处理函数,举个简化的例子:

signal(SIGUSR1, handler);
void handler(int sig){
    
    //...
    _exit(some_variable);
}

目标是停止进程并使其返回some_variable 值给父级而不使其成为全局变量。请注意,some_variable 是捕获信号的项目的本地,而不是引发信号的进程。

我希望能够在另一个进程 (kill)(不是父 btw)中发出信号,并且能够从控制台 (kill) 或使用脚本来完成,那就是使用signal() 的主要原因,因为它对两者都有好处。

我知道还有其他方法可以做到这一点,但我真的很想知道这是否可以使用signal() 或相关方法来完成。

网站上的其他线程建议不能这样做,但它们已经很老了,也许存在一些更新的解决方案。

【问题讨论】:

  • 您不能安全地在信号处理程序中使用exit(),顺便说一句,只是_exit()_Exit()。见man7.org/linux/man-pages/man7/signal-safety.7.html
  • 谁会提出SIGUSR1 信号?因为如果您使用 sigaction 并设置了 SA_SIGINFO 标志,那么根据引发信号的方式,将允许将用户指定的数据传递给信号处理程序。
  • 您可以使用SA_SIGINFOsigqueue() 将信息传递给sigaction() 的信号处理程序。
  • 我发现了一个很好的重复 stackoverflow.com/questions/6970224/… 投票结束我自己的问题,如果这有意义的话。

标签: c linux signals kill


【解决方案1】:

如果信号是从同一个进程发送的,只需使用全局变量即可。这里没有反对使用全局变量的依据/理由,因为信号处置已经是全局变量。也就是说,通过承诺为SIGUSR1 安装一个处理程序并选择它的用途,您已经选择在这里拥有一个单例;添加一个变量作为该单例的一部分不再是罪过。但是在这种情况下(相同的过程),可能没有理由使用信号处理程序。在程序的各个部分之间进行通信有各种危险得多的方式。

如果信号是从不同的进程发送的,您可以通过与sigqueue 排队的union sigval 传递少量数据(一个整数),但这仅适用于sigqueue;如果您只想使用kill 命令,它就不起作用。一旦你选择需要一个特殊的工具来进行交互,那么丢弃信号并使用一些更好的 IPC 机制(如 unix 套接字、命名管道、共享内存以及其中的一些同步原语(信号量或互斥量+condvar))会更有意义等。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-27
    • 1970-01-01
    • 1970-01-01
    • 2021-02-28
    相关资源
    最近更新 更多