【问题标题】:(f)printf() thread-safe but not signal-handler safe(f)printf() 线程安全但不是信号处理程序安全
【发布时间】:2014-09-15 08:36:35
【问题描述】:

我们最近讨论了 C(Unix 环境)中的信号处理程序。

有人提到

(f)printf() is certainly thread-safe but not signal-handler safe.

以上陈述是什么意思? (f)printf() 的哪些方面使其不是信号处理程序安全的?是不是因为它访问的是全局的标准输出和标准输入,因此该函数不能重入?

或者还有其他我遗漏的方面吗?

【问题讨论】:

  • 谁说它是线程安全的? printf 当然没有被指定为线程安全或可重入的。大多数实现可能没有太多内部共享状态(如果有的话),这可以使其被视为线程安全,但没有什么可以阻止多个线程将它们的输出混合在一起。
  • @JoachimPileborg:它是线程安全的,因为它不使用任何全局或静态局部变量。
  • @barakmanos:这是实现定义的,不是吗?标准中没有任何内容(至少到 C99)禁止 printf() 使用静态局部变量,例如对于数字转换...(那将是一个 bad 实现,但不是不合格的实现...)
  • 我也没有在 POSIX 中看到任何东西,所以这里必须在图书馆作者方面使用常识。

标签: c printf


【解决方案1】:

实际上,在信号处理程序中直接执行的合法操作很少。相反,通常必须设置一些标志或触发器才能在信号处理上下文之外进行实际工作。在处理信号时,您可以调用的唯一函数是那些“异步信号安全”的函数,详细描述如下:What constitutes asynchronous-safeness

【讨论】:

    【解决方案2】:

    这里提到:http://www.gnu.org/software/libc/manual/html_node/Nonreentrancy.html#Nonreentrancy

    如果一个函数使用并修改了一个你提供的对象,那么它就是 潜在的不可重入;如果他们使用两个呼叫可能会干扰 同一个对象。

    在您的情况下,该对象是stdout。当信号到达(f)printf() 的中间并且如果您在处理程序中使用(f)printf 时,这两个数据可能会被破坏,因为它们在同一流stdout 上运行。在这种情况下,重入是根本原因。即使您只在信号处理程序中使用流,两个信号处理程序也会相互干扰。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多