Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
&引用;杀戮-15“;触发sigaction代码,但不终止我的C程序_C_Linux_Signals_Kill - Fatal编程技术网

&引用;杀戮-15“;触发sigaction代码,但不终止我的C程序

&引用;杀戮-15“;触发sigaction代码,但不终止我的C程序,c,linux,signals,kill,C,Linux,Signals,Kill,我有一个用C开发的程序。我在这个程序中添加了一个sigaction处理程序,以便在退出程序之前执行一些C代码: void signal_term_handler(int sig) { printf("EXIT :TERM signal Received!\n"); int rc = flock(pid_file, LOCK_UN | LOCK_NB); if(rc) { char *piderr = "PID file unlock failed!";

我有一个用C开发的程序。我在这个程序中添加了一个sigaction处理程序,以便在退出程序之前执行一些C代码:

void signal_term_handler(int sig)
{
    printf("EXIT :TERM signal Received!\n");
    int rc = flock(pid_file, LOCK_UN | LOCK_NB);
    if(rc) {
        char *piderr = "PID file unlock failed!";
        fprintf(stderr, "%s\n", piderr);
        printf(piderr);
    }
    exit(EXIT_SUCCESS);
}

int main(int argc, char **argv)
{
    struct sigaction sigint_action;

    sigint_action.sa_handler = &signal_term_handler;
    sigemptyset(&sigint_action.sa_mask);

    sigint_action.sa_flags = SA_RESETHAND;
    sigaction(SIGTERM, &sigint_action, NULL);
        ...........
}
注意:我的程序包含2个子线程正在运行

当我执行我的程序,然后我调用
kill-15
来终止我的程序。我收到打印在标准输出中的消息“退出:接收到术语信号!\n”,但程序未退出


我的sigaction代码中是否遗漏了一些内容?

这很可能是因为不允许您在信号处理程序中执行很多操作(调用库函数当然很粗略)

处理此类事件的正常方法是,信号处理程序设置一个变量或将正常主循环将处理的事件排队,然后退出。

exit()
不一定是异步信号安全的

要直接从信号处理程序结束进程,请调用
\u exit()
abort()


flock()
printf
函数系列的所有成员也不是异步信号保存



有关异步信号安全函数的完整列表,请参见。

我仍然怀疑您存在XY问题,即在接收到
SIGTERM
时尝试取消文件
flock()

为了实现这一点(并绕过仅能在信号接收时使用异步信号安全功能的限制),请使用以下方法:

  • 屏蔽主线程中应用程序要处理的所有信号
  • 创建一个线程
  • 通过修改线程的信号掩码,使该线程接收所有要处理的信号
  • 在这个线程中,循环使用
    sigwaitinfo()
    来接收和发送信号
  • 然后,根据该线程接收到的信号,在不受任何限制的情况下执行需要执行的操作,因为任何函数都缺少异步信号安全性

比这更糟糕的是,
flock
是一个系统调用。
exit
如果例程注册到
atexit
,也会有问题。异步信号保存是否有
flock()
的替代方法?如果没有,是否有可能实现异步信号保存?@MOHAMED:不,我没有找到一种方法来实现
flock()
async signal save,除了黑客攻击
glibc
和/或操作系统的内核之外。但是,从您在
SIGTERM
上触发的事实来看,如果您觉得您可能有XY问题:要在程序终止时执行任何操作,请使用
atexit()安装退出处理程序
将是合适的方法。下面的答案使用
atexit()
作为解决方案。我不确定提议的解决方案是否是一种保存的方法。你能确认它是否是一种保存的方法吗?@mohamed:你链接的方法不会给你带来任何好处。@mohamed:只是想澄清一下:你的基地是否打算在进程“结束”时执行某些操作?如果你删除了信号处理程序中所有非法的代码,你将被解雇eft with
if(rc){char*piderr=“…”;}
谢谢您的回答(+1)。这是一个有趣的解决方案,但我只想在退出之前解锁一个文件,仅此而已。所以添加这样的行为与我所做的相比看起来很复杂want@MOHAMED:尽管看起来有点复杂,但这是以灵活且最后也是最安全的方式处理信号响应的唯一方法,尤其是在处理关机情况时。Al因此,在多线程环境中处理handel信号是一种非常通用的方法。@MOHAMED:注意,当进程退出时,锁会自动释放;死进程不持有锁。