C++ 中的基本信号处理

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3817631/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 13:49:16  来源:igfitidea点击:

Basic signal handling in C++

c++signals

提问by KernelM

This is a pretty basic scenario but I'm not finding too many helpful resources. I have a C++ program running in Linux that does file processing. Reads lines, does various transformations, writes data into a database. There's certain variables (stored in the database) that affect the processing which I'm currently reading at every iteration because I want processing to be as up to date as possible, but a slight lag is OK. But those variables change pretty rarely, and the reads are expensive over time (10 million plus rows a day). I could space out the reads to every niterations or simply restart the program when a variable changes, but those seem hackish.

这是一个非常基本的场景,但我没有找到太多有用的资源。我有一个在 Linux 中运行的 C++ 程序,它执行文件处理。读取行,进行各种转换,将数据写入数据库。有某些变量(存储在数据库中)会影响我当前在每次迭代中读取的处理,因为我希望处理尽可能最新,但轻微的滞后是可以的。但是这些变量很少改变,而且随着时间的推移读取成本很高(每天超过 1000 万行)。我可以将读取间隔分配到每n次迭代,或者在变量更改时简单地重新启动程序,但这些看起来很hackish。

What I would like to do instead is have the program trigger a reread of the variables when it receives a SIGHUP. Everything I'm reading about signal handling is talking about the C signal library which I'm not sure how to tie in to my program's classes. The Boost signal libraries seem to be more about inter-object communication rather than handling OS signals.

我想做的是让程序在收到 SIGHUP 时触发重新读取变量。我正在阅读的有关信号处理的所有内容都在谈论 C 信号库,我不确定如何将其与我的程序的类相关联。Boost 信号库似乎更多地是关于对象间通信而不是处理操作系统信号。

Can anybody help? It seems like this should be incredibly simple, but I'm pretty rusty with C++.

有人可以帮忙吗?看起来这应该非常简单,但我对 C++ 非常生疏。

回答by John Ledbetter

I would handle it just like you might handle it in C. I think it's perfectly fine to have a stand-alone signal handler function, since you'll just be posting to a semaphore or setting a variable or some such, which another thread or object can inspect to determine if it needs to re-read the settings.

我会像你在 C 中处理它一样处理它。我认为拥有一个独立的信号处理函数是非常好的,因为你只会发布到信号量或设置一个变量或其他类似的东西,另一个线程或对象可以检查以确定它是否需要重新读取设置。

#include <signal.h>
#include <stdio.h>

/* or you might use a semaphore to notify a waiting thread */
static volatile sig_atomic_t sig_caught = 0;

void handle_sighup(int signum) 
{
    /* in case we registered this handler for multiple signals */ 
    if (signum == SIGHUP) {
        sig_caught = 1;
    }
}

int main(int argc, char* argv[]) 
{
    /* you may also prefer sigaction() instead of signal() */
    signal(SIGHUP, handle_sighup);

    while(1) {
        if (sig_caught) {
            sig_caught = 0;
            printf("caught a SIGHUP.  I should re-read settings.\n");
        }
    }

    return 0;
}

You can test sending a SIGHUPby using kill -1 `pidof yourapp`.

您可以SIGHUP使用kill -1 `pidof yourapp`.

回答by Bryan

I'd recommend checking out this linkwhich gives the details on registering a signal.

我建议查看此链接,其中提供了有关注册信号的详细信息。

Unless I'm mistaken, one important thing to remember is that any function inside an object expects a referent parameter, which means non-static member functions can't be signal handlers. I believe you'll need to register it either to a static member function, or some kind of global function. From there, if you have a specific object function you want to take care of your update, you'll need a way to reference that object.

除非我弄错了,要记住的一件重要事情是对象内的任何函数都需要一个引用参数,这意味着非静态成员函数不能作为信号处理程序。我相信您需要将它注册到静态成员函数或某种全局函数。从那里开始,如果您有一个要处理更新的特定对象函数,则需要一种引用该对象的方法。

回答by wallyk

There are several possibilities; it would not necessarily be overkill to implement all of them:

有几种可能性;实施所有这些不一定是矫枉过正:

  • Respond to a specific signal, just like C does. C++ works the same way. See the documentation for signal().
  • Trigger on the modification timestamp of some file changing, like the database if it is stored in a flat file.
  • Trigger once per hour, or once per day (whatever makes sense).
  • 响应特定信号,就像 C 一样。C++ 的工作方式相同。请参阅 的文档signal()
  • 触发某些文件更改的修改时间戳,例如存储在平面文件中的数据库。
  • 每小时触发一次,或每天触发一次(只要有意义)。

回答by yasouser

You can define a Boost signal corresponding to the OS signal and tie the Boost signal to your slot to invoke the respective handler.

您可以定义与 OS 信号对应的 Boost 信号,并将 Boost 信号绑定到您的插槽以调用相应的处理程序。