简体   繁体   English

C程序,将参数传递给信号处理程序函数?

[英]C Program, Pass Arguments into Signal Handler Function?

I have a possible " It Can't Be Done! " problem, which I'd like to bounce off the community. 我可能遇到“ 无法完成! ”的问题,我想从社区中恢复过来。

I'm working the libIPFIX program, written in C. At the start of the code, the program sets up a Signal Handler function: 我正在使用用C编写的libIPFIX程序。在代码的开头,该程序设置了Signal Handler函数:

void exit_func ( int signo )
{
    if ( verbose_level && signo )
        fprintf( stderr, "\n[%s] got signo %d, bye.\n\n", progname, signo );

    ...clean up global variables...

    exit( 1 );
}

Later in main(), the signal handler is wired into the larger code: 稍后在main()中,信号处理程序连接到较大的代码中:

int main (int argc, char *argv[])
{
    ...

    // signal handler
    signal( SIGKILL, exit_func );
    signal( SIGTERM, exit_func );
    signal( SIGINT,  exit_func );

    ...

    exit(1);
}

Pretty boilerplate, from what I can tell. 据我所知,这很漂亮。

Here's my issue: I'm tracking a lot of extra data in my modified version of the program, using malloc() and linked lists and whatnot. 这是我的问题:我正在使用malloc()和链表以及其他功能跟踪程序修改版中的大量额外数据。 When the code detects a signal, it would be great if exit_func() could call my cleanup() functions to eliminate memory leaks, blah blah blah. 当代码检测到信号时,如果exit_func()可以调用我的cleanup()函数来消除内存泄漏,那就太好了。 What I'd love is this: 我想要的是:

void exit_func ( int signo, LLNode* myData )
{
    ...same...

    cleanUp( myData );

    exit( 1 );
}

But a reading of sigaction plus posts like these plus my own experimenting strongly suggest that there isn't a way to pass in an additional argument to exit_func() . 但阅读的sigaction加帖喜欢这些再加上我自己的强烈的实验表明,有没有额外的参数传递给方法exit_func() And that the only way to do what I want is to make my data into a global variable. 而要做我想要的唯一方法就是将我的数据变成一个全局变量。 I'd really hate to do that for other design reasons. 由于其他设计原因,我真的很讨厌这样做。

So I thought I'd go for broke and just ask: Is there was way to pass an argument into exit_func() ? 所以我想我会破产的,只是问:是否有办法将参数传递给exit_func() Thanks in advance. 提前致谢。

You cannot send arguments to a signal handler. 您不能将参数发送到信号处理程序。 Anything that needs to be accessed from the handler needs to be put into some kind of global struct. 需要从处理程序访问的所有内容都需要放入某种全局结构中。

Your original code is already wrong (even if it appears to work; it still is already undefined behavior ). 您的原始代码已经是错误的 (即使它看起来可以工作;它仍然已经是undefined behavior )。 Read first the signal (IPC) wikipage. 首先阅读信号(IPC)维基页面。

The original signal handler exit_func is already wrong. 原始信号处理程序exit_func已经错误。 Read signal(7) and signal-safety(7) . 读取signal(7)signal-safety(7) Neither exit , nor fprintf , can be called, even indirectly from a signal handler, because they are not async-signal-safe (and neither is malloc ). 即使它们既不是异步信号安全的 (也不是malloc ),甚至不能从信号处理程序间接调用exitfprintf

You'll better set some volatile sig_atomic_t variable in your signal handler, and test it in your event loops (see this and POSIX documentation on signal.h ). 您最好在信号处理程序中设置一些volatile sig_atomic_t变量,并在事件循环中对其进行测试(请参阅signal.h上的 此内容POSIX文档 )。 This is usual practice (and once you do that, which you have to do to be compliant with the signal(7) and signal-safety(7) rules, your question becomes irrelevant). 这是通常的做法(一旦这样做,必须遵循signal(7)signal-safety(7)规则,您的问题就变得无关紧要了)。

You might be interested by the Linux-specific signalfd(2) (it has some minor flaws. STFW for them). 您可能对特定于Linux的signalfd(2)感兴趣(它有一些小缺陷。对于它们来说是STFW)。

The Qt documentation has a nice chapter for Calling Qt functions from Unix signal handlers . Qt文档中有一章很好地介绍了如何从Unix信号处理程序中调用Qt函数 Some of the wisdom there (eg the pipe(7) to self trick) may apply to your program, even if it does not use Qt. 即使不使用Qt,那里的一些智慧(例如,自我欺骗的pipe(7) )也可能适用于您的程序。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM