C++ 在信号处理程序中打印?

3 c++ unix linux signals cout

我搜索了很多,但没有人回答我的问题,我读到在信号处理程序中使用 cout 是不安全的:

void ctrlZHandler(int sig_num) {
    //SIGTSTP-18
    std::cout << "smash: got ctrl-Z" << std::endl;
    SmallShell::route_signal(sig_num);
}
Run Code Online (Sandbox Code Playgroud)
  1. 如果我将打印移到route_signal内可以解决问题吗?

  2. C++11 中是否有安全调用函数列表?

  3. 如果使用 write 的唯一解决方案会怎样,您能给我看一个简短的示例吗?假设route_signal 有 100 个打印,我应该将其全部替换为 吗write()?这听起来很累人,需要分配内存和释放......

Jam*_*eod 5

信号处理程序需要快速运行并可重入,这就是为什么它们不应该直接或间接调用 cout << 等输出流函数。

\n

如果您在受控条件下临时执行此操作以进行测试,可能没问题,但请确保在处理程序完成之前不会再次触发您正在处理的信号,并注意流函数可能很慢,这可能会扰乱您的测试以及。

\n

  • 如果您知道为什么不安全,您可以回答自己的问题。 (2认同)
  • 这回答了 1,并为您指明了 2 的正确方向(查找您正在开发的环境的可重入函数列表)。 (2认同)

Det*_*nar 5

std::cout不建议使用内部信号处理程序的原因是因为信号可能随时中断正在运行的代码并且std::cout::operator <<不可重入。

std::cout::operator <<这意味着,如果您在发出信号时执行,而该信号也在执行过程中使用该信号,则结果是未定义的。

所以不行。将其移入route_signal并不能解决此问题,您应该替换std::cout其中的每个调用!

一种解决方法是设置一个标志来表明已收到该信号,并在信号返回后在信号处理程序外部创建一个输出。