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

由于printf不是可重入的,因此在信号处理程序中使用它并不安全。但是我看过很多使用printf这种方式的示例代码。

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

回答:

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

printf从信号处理程序中调用所有函数(例如)是不安全的。一种有用的技术是使用信号处理程序设置a flag,然后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

回到顶部