捕获信号:使用成员函数作为信号处理程序
Catching signals: Use a member function as signal handler
我有一个对象,它在无限循环中做一些工作。main()
实例化对象并调用 run()
方法。由于我不想使用线程,因此需要一个解决方案来使我的对象停止运行。下面你看看我想出了什么。
struct Foo
{
void run()
{
running = 1;
while (running)
do_something_useful();
std::cout << "Execution stopped." << std::endl;
}
bool running;
void catch_signal(int signal)
{
std::cout << "Caught signal " << signal << std::endl;
if( signal == SIGTERM )
running = false;
}
};
如您所见,我需要异步发送信号。因此,我使用信号处理程序并sigaction
.在我能想象到使用的main
下面。
int main(int argc, char** argv)
{
Foo foo;
struct sigaction sigIntHandler;
boost::function< void (int) > f;
f = std::bind1st(
std::mem_fun(&Foo::catch_signal), &foo);
f(5); // this call works
sigIntHandler.sa_handler = f; // compiler complains, "cannot assign ..."
sigemptyset(&sigIntHandler.sa_mask);
sigIntHandler.sa_flags = 0;
sigaction(SIGTERM, &sigIntHandler, NULL);
s.run();
}
我现在所期望的:程序运行,直到我发送SIGTERM
被捕获并导致我的对象停止迭代并返回到 main。
我现在有两个问题:
(a)在代码中,您看到一行标有"编译器抱怨"的行,消息类似于
boost::function<void(int)> cannot be converted to __sighandler_t {aka void (*)(int)}
我需要更改什么才能完成这项工作?我认为f
就像void f(int)
,就像信号处理程序在某些示例中获得的功能一样。
(b)对于那些想知道"那个家伙在做什么?"的人:你有什么建议如何更好地解决这种事情吗?
- 我需要更改什么才能完成这项工作?我认为 f 就像 void f(int),就像信号处理程序在某些示例中获得的函数一样。
编译器抱怨类型,因此您需要传递函数指针,而不是类型为 boost::function<void(int)>
的对象。创建一个这种类型的全局变量,并添加一个调用这个对象的函数就可以了:
boost::function<void(int)> myCb;
void CallCb( int value )
{
myCb(value);
}
int main(int argc, char** argv)
{
Foo foo;
struct sigaction sigIntHandler;
myCb = std::bind1st(
std::mem_fun(&Foo::catch_signal), &foo);
f(5); // this call works
sigIntHandler.sa_handler = CallCb;
sigemptyset(&sigIntHandler.sa_mask);
sigIntHandler.sa_flags = 0;
sigaction(SIGTERM, &sigIntHandler, NULL);
s.run();
}
- 你有什么建议如何更好地解决这种事情吗?
没有。这个想法还可以。我只会 c++11 lambda 代替
信号处理程序中可以移植执行的操作很少。基本上,您可以将值存储在类型为 sig_atomic_t
的对象中。插入cout
,例如,不必工作。如果您有 C++11,则可以使用原子类型或显式围栏做更多的事情,但对标准库的任何其他调用都不需要执行任何明智的操作。
因此,综上所述,您可以做的是编写一个函数(自由函数或静态成员函数(但这里有一个微妙的问题C++链接:形式上静态成员函数不起作用,但实际上它总是如此))调用成员函数,进而将running
设置为false
(假设您已将running
类型更改为sig_atomic_t
)。
- 获取日期异步信号安全吗?如果在信号处理程序中使用,它会导致死锁吗
- 如何在信号处理程序和普通函数中对全局变量进行互斥读写操作
- 有可能在信号处理程序中设置promise吗
- 在信号处理程序中捕获C++未处理的异常并恢复应用程序
- 调试和自由执行中的信号处理
- std::string 构造函数如何处理固定大小的 char[]?
- 模板函数如何处理可能共享一个交集的多个类型名称?
- 通过安装信号处理程序关闭多线程应用程序
- 为什么这个噪声函数不处理否定参数?
- 为什么我的信号处理程序只执行一次?
- 如何在C++中使用 std::bind 函数作为信号处理程序?
- 窗口上信号处理程序的异步安全写入函数
- 如何使用unique_ptr声明调用构造函数并处理程序终止信号
- 当程序遇到故障时,如何在信号处理函数中写入日志和上传日志到MYSQL
- 捕获信号:使用成员函数作为信号处理程序
- Linux 中的信号处理和中断的函数调用
- 是否有任何本机 gtkmm 类可以从小部件的信号处理程序函数中排队命令/数据
- 信号处理程序与虚拟函数和继承(事件处理)
- 信号处理程序异步安全函数
- 在信号处理程序中不允许对象或函数