c++ - 在中断信号上实现服务器停止操作的最佳方法是什么?
问题描述
我正在编写一个带有永久循环的小型服务器,我希望能够正确停止它,例如,在 Ctrl + C (SIGINT) 上。
class Server
{
...
public:
void loop()
{
while(_run_flag)
{
// do something
}
}
void stop()
{
_run_flag = 0;
}
...
private:
volatile sig_atomic_t _run_flag = 1;
};
namespace
{
std::function<void()> callback_wrapper;
void signal_handler(int)
{
callback_wrapper();
}
}
int main()
{
std::unique_ptr<WSGIServer> server = CreateServer("127.0.0.1", 4009);
callback_wrapper = [&](){ server->stop(); };
struct sigaction sigIntHandler;
sigIntHandler.sa_handler = signal_handler;
sigemptyset(&sigIntHandler.sa_mask);
sigIntHandler.sa_flags = 0;
sigaction(SIGINT, &sigIntHandler, NULL);
server->loop();
return 0;
}
我有以下问题:
run_flag_variable
我应该使用什么类型的?使用volatile sig_atomic_t
正常吗?- 调用
stop
方法是否安全signal_handler
?
解决方案
似乎几乎是合法的,除了我可以建议一些改进。一个不是那么严重:如果你只能使用 C++,我的意思是原语形式csignal
的标题,并尽量避免volatile
我们已经有东西,更多你可以在这里atomic
阅读我的答案,认为这个问题无关紧要。第二,在信号处理程序中你可以做什么和不能做什么有很多警告,C++-14,17 发生了很大变化,除了有一些非标准,但特定于平台的做事方式,但最简单的规则是你必须使用原子/易失性的东西,如果你不这样做,你必须有充分的理由并且是特定于平台的。
std::atomic_bool global_run_flag(true);
class Server {
public:
Server() : _local_run_flag(true) {}
void loop() {
while (_local_run_flag && global_run_flag) {
// do something
}
}
void stop() { _local_run_flag = false; }
private:
std::atomic_bool _local_run_flag;
};
void signal_handler(int) { global_run_flag = false; }
int main() {
std::unique_ptr<Server> server(new Server);
std::signal(SIGINT, &signal_handler);
server->loop();
return 0;
}
我举了一个例子,你可以如何跟踪一个信号处理程序的全局条件集,以及一个本地的,如果你需要的话,从其他线程设置,例如。
推荐阅读
- python - Numpy 数组到张量
- asp.net-mvc - 我有用于向他们发送邮件的用户列表。我想在另一个列表框中显示选定的用户。我怎样才能做到这一点?
- javascript - 如何以正确的方式使用抽屉反应原生?
- java - 如何使用 selenium java 识别 chrome 中正在进行的下载?
- mysql - 如何在 Node.js 中创建动态数据库连接?
- c++ - 无法在 Linux 上运行 C++ ZMQ 项目的可执行文件
- apache-spark - 具有大量读写和与 Spark Structured Streaming 集成性能的数据存储
- python - 用于输入值和获取方程式的标识符中的无效字符
- hive - Presto 失败:com.facebook.presto.spi.type.VarcharType
- linux - 商店 ls | 排序-n | head -1 < this 进入变量 shell 脚本