c - 如何避免在信号处理程序中使用 printf?

printf不可重入,在信号处理程序中使用它不应该是安全的。但是我看过很多使用 printf 的示例代码这样。

所以我的问题是:我们什么时候需要避免使用 printf在信号处理程序中,是否有推荐的替代品?

最佳答案

您可以使用一些标志变量,在信号处理程序中设置该标志,并基于该标志调用 printf()正常运行期间 main() 或程序的其他部分中的函数。

It is not safe to call all functions, such as printf, from within a signal handler. A useful technique is to use a signal handler to set a flag and then check that flag from the main program and print a message if required.



请注意,在下面的示例中,信号处理程序 ding() 设置了一个标志 alarm_fired到 1,因为 SIGALRM 被捕获并在主函数中 alarm_fired检查 value 以有条件地正确调用 printf。
static int alarm_fired = 0;
void ding(int sig) // can be called asynchronously
{
  alarm_fired = 1; // set flag
}
int main()
{
    pid_t pid;
    printf("alarm application starting\n");
    pid = fork();
    switch(pid) {
        case -1:
            /* Failure */
            perror("fork failed");
            exit(1);
        case 0:
            /* child */
            sleep(5);
            kill(getppid(), SIGALRM);
            exit(0);
    }
    /* if we get here we are the parent process */
    printf("waiting for alarm to go off\n");
    (void) signal(SIGALRM, ding);
    pause();
    if (alarm_fired)  // check flag to call printf
      printf("Ding!\n");
    printf("done\n");
    exit(0);
}

引用:Beginning Linux Programming, 4th Edition , 在这本书中,您的代码得到了确切的解释(您想要什么),第 11 章:进程和信号,第 484 页

此外,在编写处理程序函数时需要特别小心,因为它们可以被异步调用。也就是说,处理程序可能会在程序中的任何时候被不可预测地调用。如果两个信号在很短的时间间隔内到达,一个处理程序可以在另一个处理程序中运行。并且声明 volatile sigatomic_t 被认为是更好的做法,这种类型总是以原子方式访问,避免中断访问变量的不确定性。 (阅读:Atomic Data Access and Signal Handling 详细解释)。

阅读 Defining Signal Handlers : 学习如何编写可以使用 signal() 建立的信号处理函数或 sigaction()功能。
manual page中的授权功能列表,在信号处理程序中调用此函数是安全的。

https://stackoverflow.com/questions/16891019/

相关文章:

linux - 如何在登录后将 SSH 用户限制为一组预定义的命令?

python - 如何计算 NumPy bool 数组中真实元素的数量

python - 资源,客户端和 session 之间的boto3差异?

linux - 我应该使用 libc++ 还是 libstdc++?

c - Linux内核代码中的__init是什么意思?

linux - 使用 Bash 按列拆分命令输出?

python - 为什么两个相同的列表有不同的内存占用?

.net - Raspberry Pi 上的单声道

python - UnicodeEncodeError : 'charmap' codec can'

linux - 如何在不保留目录结构的情况下 tar 目录?