c++ - 结束Unix中的两个告警信号并统计SIGINT

标签 c++ linux

#include <iostream>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
using namespace std;

int count = 0; 

void alarm2(int signo)
{
    cout << count;
}

void alarm1(int signo)
{
    signal(SIGALRM, alarm2);
    cout << "ctrl+C";
    alarm(10);
    sleep(10);
}

int main()
{
    signal(SIGALRM, alarm1);

    alarm(3);
    sleep(5);
}

我希望在 3 秒后收到消息“ctrl+C”,然后再设置一个 10 秒的闹钟;之后我应该得到 count 的值。但是,当我在 10 秒后运行时,我得到了“ctrl+C”和 count 的值。

最佳答案

在您的示例中,您犯了很多很多错误。

首先查看关于从哪个函数可以安全调用的文档 信号处理程序: https://www.securecoding.cert.org/confluence/display/seccode/SIG30-C.+Call+only+asynchronous-safe+functions+within+signal+handlers

当然可以分配内存的函数调用起来是不安全的,因为调用malloc是不安全的。 因为在信号处理程序中调用 printf 或 std::ostream::opeartor<< (std::cout <<) 是不正确的。

其次,在文档(type man 3 sleep)中明确写明混合 sleep 和警报是不安全的

第三,您在 main 函数中没有等待足够的时间,因此它可以在第二个警报处理程序运行之前退出。

具体做法如下:

#include <unistd.h>
#include <stdio.h>
#include <signal.h>

volatile sig_atomic_t done = 0;

void alarm2(int signo)
{
    write(STDOUT_FILENO, "alarm2\n", sizeof("alarm2\n") - 1);
    done = 1;
}

void alarm1(int signo)
{
  signal(SIGALRM, alarm2);
  write(STDOUT_FILENO, "ctrl+C\n", sizeof("ctrl+C\n") - 1);
  alarm(10);
}

int main()
{
  signal(SIGALRM, alarm1);

  alarm(3);

  while (done == 0)
    sleep(1); //sleep can be wake up by alarm signal, so check flag    
}

关于c++ - 结束Unix中的两个告警信号并统计SIGINT,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17638914/

相关文章:

c++ - 从 'xxxx' 转换为 'yyyy' ,可能丢失数据,抑制?

linux - Linux 中读取文件

c - 为什么组长无法在 Linux 中创建 session

c - 使用套接字的文件传输服务器/客户端

Linux NASM 检测 EOF

c++ - 你会使用 num%2 还是 num&1 来检查一个数字是否是偶数?

c++ - 实现信号量、锁和条件变量

c++ - 长除法余数的模式匹配

java - 在java代码中将Windows风格的路径转换为unix路径

c++ - 在要连接的宏中扩展 C++ 宏