pat*_*ato 3 c++ unix linux posix c++11
在C++ 11中,在给定一种请求循环(作为Web请求循环的一部分)的情况下,对被捕获的信号执行不安全代码的最安全(并且是最有效的)方法是什么?例如,从linux命令行捕获SIGUSR1时:kill -30 <process pid>
"不安全代码"可以在下一个被触发的请求上运行,如果在运行不安全代码之前多次触发信号,则不会丢失任何信息.
例如,我目前的代码是:
static bool globalFlag = false;
void signalHandler(int sig_num, siginfo_t * info, void * context) {
globalFlag = true;
}
void doUnsafeThings() {
// thigns like std::vector push_back, new char[1024], set global vars, etc.
}
void doRegularThings() {
// read filesystem, read global variables, etc.
}
void main(void) {
// set up signal handler (for SIGUSR1) ...
struct sigaction sigact;
sigact.sa_sigaction = onSyncSignal;
sigact.sa_flags = SA_RESTART | SA_SIGINFO;
sigaction(SIGUSR1, &sigact, (struct sigaction *)NULL);
// main loop ...
while(acceptMoreRequests()) { // blocks until new request received
if (globalFlag) {
globalFlag = false;
doUnsafeThings();
}
doRegularThings();
}
}
Run Code Online (Sandbox Code Playgroud)
我知道在主循环测试中可能存在问题+设置globalFlag布尔值.
编辑:if (globalFlag)测试将在相当紧密的循环中运行,并且"偶尔"的假阴性是可接受的.但是,我怀疑Basile Starynkevitch的解决方案还没有优化?
你应该申报你的国旗
static volatile sig_atomic_t globalFlag = 0;
Run Code Online (Sandbox Code Playgroud)
参见例如sig_atomic_t,这个问题 并且不要忘记volatile限定符.(它可能是sigatomic_t为C 拼写的).
在Linux(特别是)上,您可以使用signalfd(2)获取信号的文件描述符,并且fd可以由事件循环进行轮询(2).
一些事件循环库(libevent,libev ...)知道如何处理信号.
在初始化时还有设置管道(参见pipe(2)以获取更多信息)的技巧,只需在信号处理程序中写入(2) -s上的某个字节.事件循环将轮询并读取该管道.
同时读取信号(7)(它解释了信号处理程序中可用的有限功能或系统调用的内容)....
顺便说一句,正确性比效率更重要.通常,您获得的信号很少(例如,大多数程序最多每秒钟获得一次信号,而不是每毫秒一次).
| 归档时间: |
|
| 查看次数: |
2153 次 |
| 最近记录: |