【问题标题】:Thread 1 reads from file as thread 2 writes to same file线程 1 读取文件,线程 2 写入同一文件
【发布时间】:2018-11-14 14:38:57
【问题描述】:

线程 1 (T1) 创建文件使用

FILE *MyFile = tmpfile();

线程 2 (T2) 然后开始写入文件。在线程 2 写入时,线程 1 偶尔会从文件中读取。

我将其设置为在 T1 正在读取时暂时挂起 T2,但是由于 T1 只读取文件的一部分,T2 不会写入(文件是按顺序写入的),我想知道是否挂起T2 是必要的。我知道如果 FILE 被固定大小的数组/向量替换,这将是可以的。只是想知道光盘与内存有何不同。

编辑。

使用 fseek 和 fwrite 完成写入。读取是使用 fseek 和 fread 完成的。我认为这是给定的,但可能不是来自某些 cmets。我想如果 T1 fseeks 到位置 X 与 T2 fseeks 到位置 Y 的同时,那么谁知道下一次读取或写入将从哪里开始。将看看管道,感谢您的帮助。

【问题讨论】:

  • 当您的第二个线程正在修改内存而线程 1 正在监视它时,即使在线程之间共享内存也会导致未定义的行为。线程 1 可能会看到“半状态”(即在线程 2 仍在忙于将内容写入内存时读取)。您需要类似互斥锁的东西来确保一次只有一个线程在访问它。
  • 感谢您的回复。我已经编辑了我的问题以阅读固定大小的数组/向量。 Re FILE,可以同时读写吗?磁盘操作系统会不会收到诸如写、写、写、读、写之类的请求并按照它们到达的顺序处理它们?
  • 文件读/写与磁盘I/O有关,就像栈/堆到内存一样。 T1 和 T2 可以通过锁相互排斥。
  • 不是一个好主意。文件很难用作 IPC 的一种形式。如果需要数据库,请使用数据库。
  • 如果您需要传递数据,请使用专为传递数据而设计的工具,例如管道。不是专为存储/保存数据而设计的。

标签: c++ windows multithreading file


【解决方案1】:

在处理单个线程时,在 FILE 上混合读取和写入甚至是不安全的。来自 fopen 的手册页:

读和写可以以任何顺序在读/写流上混合。请注意,ANSI C 要求文件定位函数在输出和输入之间进行干预,除非输入 操作遇到文件结尾。 (如果不满足此条件,则允许读取 返回除最近写入之外的写入结果。)因此,这是一种很好的做法(并且 在 Linux 下确实有时需要)在两者之间放置 fseek(3) 或 fgetpos(3) 操作 对此类流的写入和读取操作。此操作可能是明显的无操作(如 fseek(..., 0L, SEEK_CUR) 调用它的同步副作用)。

所以不要假设读取​​和写入会为您神奇地同步并使用互斥锁保护对 FILE 的访问。

【讨论】:

  • 但是如果他打开文件两次呢?我可以看到生产者和消费者都打开带有共享标志的文件。但我同意@Andrew Henle 的观点,他说最好使用管道。 OP 使用的是 Windows,因此他甚至可以在消息模式下打开管道,因此他甚至不必将传入字节流拆分为单独的消息...
  • 那更糟,因为你有 2 个带有单独缓冲区的 FILE 流。一个文件中的写入不会出现在另一个文件中,除非它被刷新到磁盘。是的,管道更适合线程之间的通信。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多