glibc的fprintf()实现是否线程安全?

8
fprintf线程安全吗?glibc手册似乎是这样说的,但我的应用程序使用单个fprintf()调用写入文件时,似乎会混杂来自不同进程的部分写入。编辑:为了澄清,涉及的程序是一个lighttpd插件,服务器正在运行多个工作线程。查看文件,一些写入是混杂在一起的。编辑2:看起来我看到的问题可能是由于lighttpd的“工作线程”实际上是单独的进程导致的:http://redmine.lighttpd.net/wiki/lighttpd/Docs:MultiProcessor

问题

在同一个套接字上运行两个或更多进程,可以获得更好的并发性,但需要注意以下一些缺点:

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

你是在使用fprintf写入文件时观察到这个问题,还是在stdoutstderr流中观察到的? - Craig S
3个回答

14

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

在一个进程内,可以确保一次fprintf调用完成后才允许下一次访问输出缓冲区,但一旦您的应用程序将该输出传输到文件中,您就要看操作系统的脸色了。如果没有某种基于操作系统的锁定机制,您无法确保完全不同的应用程序不会写入您的日志文件。


7
听起来你需要阅读关于文件锁定的内容。你所遇到的问题是多个进程(而不是线程)同时写入同一文件,没有可靠的方法来确保写操作是原子性的。这可能导致文件覆盖彼此的写入、混合输出和完全不确定的行为。
这与线程安全无关,因为它仅适用于单进程多线程程序。

2
当前的C++标准和1990年的C标准对并发性没有任何有用的说明。 (我没有阅读1999年的C标准,因此无法发表评论;即将推出的C++0x标准确实有所规定,但我不知道具体情况。)
这意味着fprintf()本身很可能既不是线程安全的,也不是其他方面的安全,而且这取决于实现。我建议您仔细阅读glibc文档中的内容,并将其与您正在执行的操作进行比较。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接