【问题标题】:Is glibc's implementation of fprintf() thread-safe?glibc 的 fprintf() 实现是线程安全的吗?
【发布时间】:2009-02-27 13:56:54
【问题描述】:

fprintf 是线程安全的吗? The glibc manual 似乎是这样说的,但是我的应用程序,它使用对 fprintf() 的单次调用写入文件,似乎混合了来自不同进程的部分写入。

编辑:澄清一下,有问题的程序是一个lighttpd 插件,并且服务器使用多个工作线程运行。

查看文件,有些写入是混合在一起的。

编辑 2:看来我看到的问题可能是由于 lighttpd 的“工作线程”实际上是单独的进程:http://redmine.lighttpd.net/wiki/lighttpd/Docs:MultiProcessor

问题

通过在 同样的插座你会有更好的 并发,但会有一些 您必须注意的缺点 的:

  • mod_accesslog 可能会创建损坏的访问日志,因为同一个文件打开了两次并且未同步。
  • mod_status 将有 n 个单独的计数器,每个计数器一组 过程。
  • mod_rrdtool 将失败,因为它两次收到相同的时间戳。
  • mod_uploadprogress 不会显示正确的状态。

【问题讨论】:

  • 您是在使用fprintf 编写的文件中观察到这一点,还是在stdoutstderr 流中观察到这一点?

标签: c multithreading posix lighttpd printf


【解决方案1】:

您混淆了两个概念 - 从多个线程写入和从多个进程写入。

在进程内部,可以确保在允许访问输出缓冲区之前完成一次 fprintf 调用,但是一旦您的应用程序将该输出泵送到文件中,您就会受到操作系统的支配。如果没有某种基于操作系统的锁定机制,您将无法确保完全不同的应用程序不会写入您的日志文件。

【讨论】:

    【解决方案2】:

    在我看来,您需要阅读 file locking。您遇到的问题是多个进程(即不是线程)同时写入同一个文件,并且没有可靠的方法来确保写入是原子的。这可能导致文件覆盖彼此的写入、混合输出以及完全不确定的行为。

    这与线程安全无关,因为这仅在单进程多线程程序中相关。

    【讨论】:

      【解决方案3】:

      当前的 C++ 标准对并发没有任何用处,1990 年的 C 标准也没有。 (我没有读过 1999 年的 C 标准,所以不能评论它;即将到来的 C++0x 标准确实说了一些话,但我不知道究竟是什么。)

      这意味着 fprintf() 本身可能既不是线程安全的,也不是其他的,它取决于实现。我会准确阅读 glibc 文档中关于它的内容,并将其与您正在做的事情进行比较。

      【讨论】:

        猜你喜欢
        • 2014-04-27
        • 2018-06-04
        • 2012-05-20
        • 1970-01-01
        • 1970-01-01
        • 2021-05-12
        • 1970-01-01
        • 2010-12-10
        • 1970-01-01
        相关资源
        最近更新 更多