gpt4 book ai didi

c++ - Visual C++ 2015 中的 SIGINT 处理程序重置

转载 作者:搜寻专家 更新时间:2023-10-31 02:13:20 24 4
gpt4 key购买 nike

考虑下面的测试程序

#include <csignal>
#include <iostream>

volatile std::sig_atomic_t signal_raised = 0;

void set_signal_raised(int signal) {
signal_raised = 1;
}

void check(std::sig_atomic_t expected) {
if (signal_raised != expected) {
std::cerr << signal_raised << " != " << expected << std::endl;
abort();
}
}

int main() {
using namespace std;
check(0);
std::signal(SIGINT, set_signal_raised);
check(0);
std::raise(SIGINT);
check(1);
signal_raised = 0;
check(0);
std::raise(SIGINT);
check(1);
cerr << "OK.\n";
}

对于 GCC 和 Clang,它输出“OK”。但是,对于 Visual Studio 2015,它不输出任何内容。

信号处理程序在处理完第一个信号后被重置。这可以通过添加

来验证
auto prev = std::signal(SIGINT, set_signal_raised);
if (prev != set_signal_raised) {
std::cerr << "Unexpected handler." << std::endl;
abort();
}

检查功能。这是允许和预期的吗?

最佳答案

信号配置的重置是 Unix System V 使用的行为。但是 BSD(目前是 glibc)不会重置信号配置。 POSIX 标准允许任何一种行为。 C标准没有指定是否允许“重置”。

来自 signal(2) :

POSIX.1 solved the portability mess by specifying sigaction(2), which provides explicit control of the semantics when a signal handler is invoked; use that interface instead of signal().

In the original UNIX systems, when a handler that was established using signal() was invoked by the delivery of a signal, the disposition of the signal would be reset to SIG_DFL, and the system did not block delivery of further instances of the signal. This is equivalent to calling sigaction(2) with the following flags:

sa.sa_flags = SA_RESETHAND | SA_NODEFER;

System V also provides these semantics for signal(). This was bad because the signal might be delivered again before the handler had a chance to reestablish itself. Furthermore, rapid deliveries of the same signal could result in recursive invocations of the handler.

因此,Visual Studio 似乎遵循了 System V 的行为。

Is this allowed and expected?

这是允许的,但绝对不希望这样做。为此,POSIX 引入了 sigaction() .如果你有 sigaction() 然后使用它。否则,您只需每次在信号处理程序中重新安装处理程序:

void set_signal_raised(int signal) {
std::signal(SIGINT, set_signal_raised);
signal_raised = 1;
}

关于c++ - Visual C++ 2015 中的 SIGINT 处理程序重置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41552081/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com