2009-02-27 385 views
7

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

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

看着这个文件,一些写入操作混在一起。

编辑2:看来我看到的可能是由于lighttpd的的“工作线程”,其实是分开处理的问题:http://redmine.lighttpd.net/wiki/lighttpd/Docs:MultiProcessor

问题

通过运行2个或多个进程在 相同的套接字,你将有更好的 并发,但将有几个 的缺点,你必须知道的 :

  • mod_accesslog可能造成破坏的访问日志,以相同的文件被打开两次,不同步。
  • mod_status的将具有Ñ独立的计数器,对每个 处理一组。
  • mod_rrdtool将因两次接收相同的时间戳而失败。
  • mod_uploadprogress将不显示正确的状态。
+0

你在用`fprintf`编写的文件中观察到这一点,还是在`stdout`和`stderr`流中观察了这个? – 2009-02-27 14:41:11

回答

14

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

在一个进程中,可以确保在下一个允许访问输出缓冲区之前完成一次fprintf的调用,但是一旦您的应用程序将输出输出到一个文件,您将受到OS的摆布。如果没有某种基于OS的锁定机制,则无法确保完全不同的应用程序不会写入日志文件。

7

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

这有什么好做的是线程安全,因为这只是在单进程多线程程序有关。

2

当前的C++标准没有提及并发性,也没有1990 C标准。 (我没有阅读1999 C标准,所以不能评论它;即将出现的C++ 0x标准确实说了些什么,但我不知道什么是非正式的。)

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