在SIGALRM处理程序中打印

时间:2015-01-25 11:05:14

标签: c process fork

虽然搞乱了一个类的系统调用,但是我遇到了以下代码的问题。无论出于何种原因,当信号处理程序中的print语句在其末尾有换行符时,它的行为与预期一致,信号被接收和处理,并显示消息。但是,当换行符 not 时,根本不会显示任何输出。

我不知道为什么会出现这种情况,并且希望有人可以对这个问题有所了解。

此外,当 打印某些东西时,信号似乎只被发送了四次?这段代码有各种奇怪的东西。

#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

2 个答案:

答案 0 :(得分:3)

如果由于某种原因想要显示没有行尾的内容,那么很可能有助于fflush(stdout);因为stdout被缓冲并且通常在每一行都会刷新。

答案 1 :(得分:2)

  1. 正如Henrik Carlqvisthis answer指出的那样,你观察到“缓冲输出”的影响。

  2. 同样SCCa comment中提到printf()并非异步信号安全且不会被称为信号处理程序。

  3. 要解决1.和fullfil 2.只需使用信号安全功能write()编写您的消息,此外还使用 un 缓冲I / O,因此不需要刷新。< / p>

    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));      
    }