在 SIGALRM 处理程序中打印

Printing in SIGALRM handler

在处理 class 的系统调用时,我 运行 遇到了以下代码的麻烦。无论出于何种原因,当信号处理程序中的 print 语句末尾有一个换行符时,它会按预期运行,接收和处理信号并显示消息。但是,当 not 存在换行符时,根本不会显示任何输出。

我不知道为什么会这样,希望有人能解释一下这个问题。

另外,打印东西的时候,信号好像只发送了四次?使用此代码进行各种 st运行ge 操作。

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

void alarm_handler(int signo) {
    printf("pid : %d\n", getpid());
}

int main(int argc, char* argv[]) {
    pid_t pid;
    signal(SIGALRM, alarm_handler);

    pid = fork();

    if(pid == 0)
        while(1) { }
    else
    {
        int i;
        for(i = 0; i < 5; i++)
        {
            sleep(1);
            kill(pid, SIGALRM);
        }  
        kill(pid, SIGKILL);
    }
}

GCC 版本信息

gcc -v
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer//usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 6.0 (clang-600.0.56) (based on LLVM 3.5svn)
Target: x86_64-apple-darwin14.0.0
Thread model: posix

如果您出于某种原因想要显示不带行尾的打印内容,那么这样做很可能会有所帮助 fflush(stdout);,因为标准输出已被缓冲并且通常会在行尾刷新。

  1. 正如Henrik Carlqvist in 指出的,你观察"buffered output"的效果。

  2. 另外 SCC mentions in printf() 不是异步信号安全的,不应从信号处理程序中调用。

要绕过 1. 并完成 2. 只需使用信号安全功能 write() 编写您的消息,此外还使用 un 缓冲 ​​I/O,所以不需要冲洗。

void alarm_handler(int signo) 
{
  char msg[64] = "alarm handler called";
  /* snprintf(msg, sizeof msg, "pid : %d\n", getpid()); */ /* sprintf also isn't async signal safe */
  write(fileno(stdout), msg, strlen(msg));      
}