fread线程锁定在什么级别?他们需要达到什么水平?

use*_*689 6 c c++ io multithreading locking

Visual Studio的恐惧"锁定了其他线程." 有一个备用版本_fread_nolock,它读取"不锁定其他线程",它只能用于"线程安全的上下文中,例如单线程应用程序或调用范围已处理线程隔离".

即使在阅读了关于这两者的其他有些相关的讨论之后,如果锁定fread实现在特定的FILE结构,特定的实际文件或者对完全不同的文件的所有fread调用上,我会感到困惑.

如果您使用nolock版本,您需要提供什么级别的锁定?并行多个线程可以读取单独的文件而无需任何锁定吗?并行多个线程可以写入单独的文件而不进行任何锁定吗?或者是否涉及会损坏的全局变量或静态变量?

因此,通过使用nolock版本,您是否能够实现更好的I/O吞吐量(如果您不是不必要地移动磁头,例如读取单独的驱动器或SSD驱动器),或者可能只是减少冗余锁定单锁(应该可以忽略不计.)

VS'ifstream.read函数是否像常规fread一样工作?(我没有看到它的nolock版本.)

Chr*_*phe 3

MS 标准库实现完全支持多线程。C++ 标准解释了这一要求:

\n\n
\n

27.2.3:除非另有指定,否则多个线程对流对象、流缓冲区对象或 C 库流的并发访问可能会导致数据竞争。

\n\n

如果一个线程进行库调用 a 将值写入流\n,结果,另一个线程通过库调用 b 从流\n 读取该值,这样就不会导致数据\n 竞争,则 a\xe2\x80\x99s 写入与 b\xe2\x80\x99s 读取同步。

\n
\n\n

这意味着,如果您在流上写入,则会完成锁定(不是文件锁定,而是对内存中流数据结构的并发访问锁定),以确保使用同一流的所有其他线程良好地管理并发性。

\n\n

即使不需要,这种锁定开销始终存在。根据微软的说法,这可能会影响性能:

\n\n
\n

多线程库的性能已得到改进,并且接近现已淘汰的单线程库的性能。对于需要更高性能的情况,有一些新功能。

\n
\n\n

这就是提供 _nolock 函数的原因。他们直接访问流而无需线程锁定。使用时必须极其小心,例如:

\n\n
    \n
  • 如果您的应用程序是单线程的(使用同一流的另一个进程有自己的数据结构,并且操作系统在此处管理并发)
  • \n
  • 如果您确定没有两个线程使用相同的流(例如,如果您只有一个读取器线程并且写入是在程序之外完成的)。
  • \n
  • 如果您有其他同步机制来保护代码的关键部分。例如,如果您使用互斥锁或利用原子的线程安全非阻塞算法。
  • \n
\n\n

在这种情况下,不需要/冗余用于流访问的附加锁。对于文件密集型函数,那么使用 no_lock 可能是值得的。

\n\n

注意:正如您所指出的:只有在进行数百万次访问的密集文件访问时才值得使用 nolock。

\n