【问题标题】:Can multiple threads write into a file simultaneously, if all the threads are writing to different locations?如果所有线程都写入不同的位置,多个线程可以同时写入文件吗?
【发布时间】:2011-09-27 06:26:25
【问题描述】:

我正在用 C++ 编写代码。我会遇到任何类型的竞争条件或段错误吗?

【问题讨论】:

  • 如果您需要非顺序的并发文件访问,我建议您改用内存映射文件。然后将其视为普通内存并进行自己的锁定(如果您可以保证写入/读取位置不重叠,则不需要)。

标签: c++


【解决方案1】:

从底层系统的角度来看,这样做没有问题(对于我所知道的所有系统)。但是,通常您需要完全独立的文件描述符/句柄。这是因为文件描述符保持状态,例如当前文件位置。

您还需要检查您正在使用的文件系统的特定 C++ 接口的线程安全性。除了底层文件系统的线程安全之外,这也是必需的。

您还应该考虑线程 I/O 会变慢的可能性。系统可能必须串行访问总线。您可以从重叠 I/O 或通过生产者/消费者管道馈送的专用 I/O 线程获得更好的性能。

【讨论】:

  • 在每个线程中,我打开同一个文件,然后根据每个线程不同的位置写入文件。所以,我可以继续实施对吗???
  • 我不能肯定地说。你还没有显示你的代码。但只要你有不同的手柄,你应该没问题。
【解决方案2】:

根据文件大小和您运行的系统,另一种解决方案是使用memory mapped files,即。将文件映射到虚拟内存。这将使您可以直接访问文件,就好像它是一块内存一样。这样,任意数量的线程都可以简单地写入内存区域,随后调用将映射刷新到磁盘(取决于您的内存映射配置)将简单地将数据存储在磁盘上。

请注意,由于 32 位平台的地址限制,您无法映射任何大于通常 2-3 GB 的文件,具体取决于架构和可用于执行虚拟内存的实际位数寻址。大多数 64 位系统都有 48 位或更多可用于此任务,允许您映射至少 256 TB,我认为这绰绰有余。

【讨论】:

  • 是的。几乎所有现代 UNIX 都通过 mmap 函数支持内存映射。 man 页面提供了更多详细信息,在您的情况下为like this。通常,所需的步骤只是打开一个文件描述符,必要时预分配它的大小(手动或通过 fallocate 或 posix_fallocate),然后将其映射到内存,一切顺利。
  • 但是,这里的问题是我使用哈希表来存储传入的数据,并且,我想将其写入输出文件...那么,有什么办法吗???
【解决方案3】:

这取决于。 文件不是它们的句柄,流也不是文件。 这三个不同的概念一定要搞清楚。

现在,操作系统可以多次打开文件,返回不同的句柄,每个句柄都有自己的“位置指针”。如果文件以“共享模式”打开以进行读取和写入,您可以在所需的位置查找句柄并根据需要进行读取/写入。您不覆盖的事实取决于您。系统为整个文件或部分文件授予操作的顺序性(但需要有关操作系统的更多信息)

如果每个句柄都附加到不同的流,则每个流将独立于另一个写入。但是 - 在这种情况下 - 存在“缓冲”的复杂性(写入可以延迟并且可以预期读取:并且可以根据您的要求更长:确保通过适当的刷新来正确管理最终的重叠)

【讨论】:

  • 在每个线程中,我打开同一个文件,然后根据每个线程不同的位置写入文件。所以,我可以继续实施对吗???
  • @Invictus:您必须打开文件进行共享。其他一切都应该工作。
【解决方案4】:

当然可以。根据您编写实际代码的方式(即使用该文件),可能会出现竞争条件。此外,如果 IO 被缓冲,如果缓冲区域重叠,可能会出现奇怪的事情。

【讨论】:

    猜你喜欢
    • 2012-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-06
    • 1970-01-01
    相关资源
    最近更新 更多