如何避免在信号处理程序中使用printf?
由于printf
不是可重入的,因此在信号处理程序中使用它并不安全。但是我看过很多使用printf
这种方式的示例代码。
所以我的问题是:我们什么时候需要避免printf
在信号处理程序中使用,并且有推荐的替代品吗?
回答:
您可以使用一些标志变量,在信号处理程序中设置该标志,并printf()
在正常操作期间基于main()或程序其他部分中的该标志调用函数。
printf
从信号处理程序中调用所有函数(例如)是不安全的。一种有用的技术是使用信号处理程序设置aflag
,然后flag
从主程序中检查它并在需要时打印一条消息。
注意,在下面的示例中,信号处理程序ding()alarm_fired
在捕获到SIGALRM时将标志设置为1,并alarm_fired
检查主函数值以有条件地正确调用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 LinuxProgramming,第4版,在本书中,准确说明了您的代码(所需的内容),第11章:进程和信号,第484页
此外,在编写处理程序函数时需要特别小心,因为它们可以异步调用。也就是说,处理程序可能在程序中的任何地方被意外地调用。如果两个信号在很短的间隔内到达,则一个处理程序可以在另一个处理程序中运行。并且,最好声明为volatile
sigatomic_t,始终以原子方式访问此类型,以避免不确定中断对变量的访问。(有关详细信息,请阅读:原子数据访问和信号处理)。
阅读定义信号处理程序:了解如何编写可以使用signal()
或sigaction()
函数建立的信号处理程序功能。手册页
中授权功能的列表,在信号处理程序中调用此功能是安全的。
以上是 如何避免在信号处理程序中使用printf? 的全部内容, 来源链接: utcz.com/qa/408637.html