ofstream线程是否安全?

时间:2013-11-26 08:33:12

标签: c++ multithreading

我正在开发一个程序,它使用多个std::ifstream来读取二进制文件,每个线程一个std::ifstream。现在我需要知道,如果std::ofstream在Windows和Linux上是线程安全的,那么在同一个文件中写入。我只使用一个std::ofstream并使用多个线程 我正在使用每个线程读取不同的块,并使用seekp()write()在输出文件中写入这些块。目前它对我有用,但它是否对大文件有问题。

std::ofstream线程是否安全?

4 个答案:

答案 0 :(得分:8)

如果我没有误解你 - 不,标准库中没有任何东西是线程安全的(除了std::thread特定的东西,当然(来自C ++ 11及更高版本))。您需要其他同步。

更多 - 如果有多个进程,读取/写入这些文件,则需要锁定文件,以同步访问。

答案 1 :(得分:6)

C++ standards(输入/输出库线程安全):

  

27.1.3线程安全[iostreams.thread-safety]

     

并发访问流对象[string.streams,file.streams],流缓冲区对象   多个线程的[stream.buffers]或C Library stream [c.files]可能会产生数据   race [intro.multithread]除非另有说明[iostream.objects]。 [注:数据竞赛   导致未定义的行为[intro.multithread]。

答案 2 :(得分:2)

是。它是。

对于Windows: 从Windows上的多个线程写入fstream是安全的。请参阅msdn文档:Thread Safety in the C++ Standard Library

对于Linux: 简而言之,它是。从document of libstdc++:"如果您的平台的C库是线程安全的,那么您的fstream I / O操作将是最低级别的线程安全"。您平台的C库线程是否安全?是。 POSIX标准要求C stdio FILE *操作(例如fread / fwrite)是原子的,glibc是这样做的。

答案 3 :(得分:0)

我编写了一个小程序来验证 std::ifstream 的线程安全性 和 std::ofstream https://github.com/rmspacefish/rpi-file-concurrency 。我已经在 Linux 桌面主机和 Raspberry Pi 上进行了测试。程序启动两个线程,一个写线程和一个读线程,有文本模式和二进制模式。

在文本模式下,我在写线程中写两行,读线程试图读两行。对于文本模式,我得到以下输出:

Concurrent file access test
Write Open Fail Count: 0
Write Count: 191090
Write Fail Count: 0

Read Open Fail Count: 0
Read Count: 93253
Read One Line Count: 93253
Read Both Lines Count: 93253
Faulty Read Count: 0
EOF Count: 0
Fail Count: 0

Finished.

所以这对于 Linux 来说似乎是线程安全的。对于二进制模式,我正在以由多个字段(如字符数组、各种大小的整数等)组成的结构形式编写二进制块。我有两个以交替循环写入的状态。在阅读器线程中,我检查数据的一致性(不一致的状态或更糟,错误的值)。在这里我得到以下结果

Concurrent file access test
Write Open Fail Count: 0
Write Count: 0
Write Fail Count: 0

Read Open Fail Count: 0
Read Count: 0
Blob in state one read: 25491
Blob in state two read: 24702
Blob in invalid state: 0
Faulty Read Count: 0
EOF Count: 91295
Fail Count: 91295

Finished.

我在调用 read 后检查了错误标志(这很重要)。如果没有错误标志,则以一致的方式读取状态。对我来说,它看起来是线程安全的。

线程安全可能仍然依赖于实现,但至少对于 Linux/GCC,文件访问似乎是线程安全的。我仍将在 Windows 上使用 MSVC 进行测试,但 Microsoft 指定这也应该是线程安全的。