【问题标题】:Printing in SIGALRM handler在 SIGALRM 处理程序中打印
【发布时间】:2015-01-25 11:05:13
【问题描述】:

在处理类的系统调用时,我遇到了以下代码的问题。无论出于何种原因,当信号处理程序中的 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

【问题讨论】:

  • 我不确定是不是这个问题。但是你不应该在信号处理程序中使用printf(),因为它不是async-signal-safe functions。有关功能列表,请参阅signal man page。您应该尝试将printf() 替换为write()
  • 另外,要查看第五个信号中的 printf,请将 sleep(1) 行移到 kill(pid, SIGALRM) 之后。

标签: c process fork


【解决方案1】:

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

【讨论】:

    【解决方案2】:
    1. 正如Henrik Carlqvisthis answer 中所指出的,您可以观察到“缓冲输出”的效果。

    2. 另外SCCa comment 中提到printf() 不是异步信号安全的,不应从信号处理程序中调用。

    要绕过 1. 和 fullfil 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));      
    }
    

    【讨论】:

    • 避免调用未从信号处理程序安全调用的函数是可行的方法。正如 alk 和 SSC printf 所指出的,它不在信号安全功能列表中。不幸的是,该列表中还缺少其他不错的功能,例如 sprintf。您可能希望实现自己的 itoa 函数(谷歌可能会给您一个现有代码的示例)以与 write 一起使用。
    • 抓到我了! :} @HenrikCarlqvist
    猜你喜欢
    • 2021-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-10
    • 2023-03-11
    • 1970-01-01
    • 2014-05-30
    • 1970-01-01
    相关资源
    最近更新 更多