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
Basic signal handling in C++
提问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 SIGHUP
by 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 信号绑定到您的插槽以调用相应的处理程序。