8

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

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

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

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

问题

通过在同一个套接字上运行 2 个或更多进程,您将获得更好的并发性,但您必须注意一些缺点:

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

3 回答 3

14

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

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

于 2009-02-27T14:01:31.693 回答
7

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

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

于 2009-02-27T14:09:34.403 回答
2

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

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

于 2009-02-27T15:16:11.730 回答