【问题标题】:linux/glibc. Can I use fprintf in signal handler?linux/glibc。我可以在信号处理程序中使用 fprintf 吗?
【发布时间】:2010-12-29 12:36:02
【问题描述】:

我可以在带有 glibc/linux 的信号 (SIGALRM) 处理程序中使用fprintf(stderr) 吗?

【问题讨论】:

    标签: linux signals handler glibc


    【解决方案1】:

    不,你不能。查看手册页 signal(7) 以获取异步信号安全函数列表。 fprintf 不包含在该列表中。

    如果您不需要格式化,则可以使用write(STDERR_FILENO, <buf>, <buflen>) 写入stderr。

    【讨论】:

    • 它是来自 libc 的函数列表还是内核系统调用列表?
    • @osgx:添加到答案的链接。它是一个包含 libc 标准的 posix 函数列表。但是,libc 标准不要求任何 libc 函数(signal() 除外)是可重入的,因此您不能(可移植地)在信号处理程序中使用任何 libc 函数。
    【解决方案2】:

    这不安全,引用 IBM DeveloperWorks 关于Signal Handling Safety 的文章

    假设信号处理程序使用 fprintf 打印一条消息,并且程序在传递信号时使用同一流进行 fprintf 调用。信号处理程序的消息和程序的数据都可能被破坏,因为这两个调用都在同一个数据结构上操作:流本身。

    【讨论】:

    • glibc 在 FILE* 中有一个 IO 锁。因此,确实会中断第一个 fprintf 的 fprintf 将等待
    • @osgx:信号处理程序不是线程。在信号处理程序中等待是非常坏的消息,因为持有锁的线程在信号处理程序完成之前无法取得进展。所以你有一个僵局。
    • @osgx:不,你没有说“线程”。但是您声称锁定有助于防止损坏。它不会。锁旨在同步线程之间的访问,而不是线程的主代码和同一线程的信号处理程序之间的访问。要么你有一个可重入锁,它对信号处理程序绝对没有影响并且损坏仍然发生,要么你有一个不可重入锁,这会导致死锁。在这两种情况下,fprintf 内部的锁都不会以任何方式改变“这不安全”的正确答案。
    猜你喜欢
    • 1970-01-01
    • 2019-07-20
    • 2013-05-27
    • 1970-01-01
    • 2021-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多