【问题标题】:Multiple threads writing on same file多个线程写入同一个文件
【发布时间】:2014-10-25 18:00:56
【问题描述】:

我想知道我们是否可以使用多个线程在同一个文件上写入二进制数据。

FILE *fd = openfile("test");
int SIZE = 1000000000;
int * table = malloc(sizeof(int) * SIZE);
// .. filling the table
fwrite(table, sizeof(*table), SIZE, fd);

所以我想知道我是否可以使用线程,并且每个线程都会调用 fssek 来寻找不同的位置以写入同一个文件。

有什么想法吗?

【问题讨论】:

  • 阅读fwrite() 的文档以了解它是否是线程安全的。如果没有,您将需要实现自己的互斥锁来保护它。
  • int * table = sizeof(sizeof(int) * SIZE); 这里似乎遗漏了什么。

标签: c multithreading


【解决方案1】:

fwrite 应该是线程安全的,但无论如何你都需要一个互斥体,因为你需要查找和写入是原子的。根据您的平台,您可能有一个带偏移量的写入函数,或者您可能能够在每个线程中打开文件。一个更好的选择,如果你的代码建议的一切都在内存中,那就是让每个线程填充一个大数组,然后在一切完成后将其写出来。

【讨论】:

  • 实际上我已经有一个很大的数组(表),但我想使用线程同时将“int * table”写入我的文件
  • 是因为您希望它更快吗?我认为这不太可能,因为写操作必须在某个阶段进行序列化。事实上,额外的搜索可能会显着减慢这一速度。
【解决方案2】:

虽然fread()fwrite() 是线程安全的,但FILE* 表示的流缓冲区不是。因此,您可以让多个线程访问同一个文件,但不能通过同一个 FILE* - 每个线程必须有自己的,并且它们引用的文件必须是可共享的 - 这取决于操作系统。

另一种可能更简单的方法是使用memory mapped file,以便每个线程将文件视为共享内存,让操作系统处理文件 I/O。这与普通文件 I/O 相比具有显着优势,因为它是真正的随机访问,因此您无需担心 fseek() 和顺序读/写等。

【讨论】:

  • 你是说在多线程中使用全局文件指针访问fprintf()fwrite()不安全?
  • @JohnStrood ;我没有确切地说,但是答案适用于使用FILE* 的任何函数,因为FILE 不是原子对象。此外,该问题需要独立的fseek() 操作,并且由于当前文件位置保留在FILE 对象中,因此在这种特殊情况下,如果不将整个查找/写入序列包装在两个线程的互斥锁中以确保操作的序列化,则无法使用.
  • 虽然这在某些 C99 实现中可能是正确的,但 C2011 指定“所有读取、写入、定位或查询流位置的函数在访问流之前锁定流。它们释放锁定访问完成时与流关联”(C2011 7.21.2/8)。请注意,这指的是锁定,而不是底层文件。
  • @JohnBollinger :我不清楚您指的是答案的哪一部分或后续的 cmets。那是很久以前的事了-我不确定我现在是否要更改它,但是澄清您的评论也许会很有用-即确切地说什么对C99可能是正确的?
  • @Clifford,我首先注意到我的注意力是由another answer 引导的,所以也许这对上下文有所帮助。但我指的是你的整个第一段。尽管该标准没有明确规定 FILE 对象是可共享的,但对于其有关流和流锁定的规定,没有任何可行的解释不会导致该结果。
【解决方案3】:

fseek 和 fwrite 是线程安全的,因此您无需额外同步即可使用它们。

【讨论】:

  • 但是调用 fseek 再调用 fwrite 需要同步
  • @WilliamPursell 这取决于实现。如果每个线程都有自己的文件描述符,那么在不同步的情况下一个接一个地调用它们是安全的。
  • 实现示例?
  • @zeomega 您是指无需额外同步即可正常工作的实现吗?您可以通过在每个线程中调用 fopen 在所有线程中打开相同的文件。
【解决方案4】:

让每个线程打开文件,并确保它们写入不同的位置,最后让每个线程关闭文件并完成。

更新:

这至少适用于 IX'ish 系统。

【讨论】:

  • 你有一个小例子吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多