_fread_nolock,_fseek_nolock的用途是什么?

我们有一个基本上从二进制文件中读取和写入向量的C ++类。 将单个向量载入内存的示例性读取函数如下所示:

int load (const __int64 index, T* values) const { int re = _fseeki64(_file, index * _vectorSize + _offsetData, SEEK_SET); assert(re == 0); size_t read = fread(values, sizeof(T), _vectorElements, _file); assert(read == _vectorElements); return 0;} 

Out程序是OpenMP的multithreading,multithreading同时访问同一个文件。 为了避免由于multithreading引起的问题,我们总是覆盖OpenMP临界语句中的函数调用:

 #pragma omp critical { load(...); } 

我知道Microsoft Visual C ++运行时包含_fseek_nolock_fread_nolock_fwrite_nolock等几个函数…例如_fread_nolock()函数被描述为

这个函数是fread的一个非locking版本。 除了不受其他线程的干扰之外,它与fread相同。 这可能会更快,因为它不会导致locking其他线程的开销。 仅在线程安全的上下文(如单线程应用程序或调用作用域已经处理线程隔离的情况下)使用此函数。

现在我的问题:我知道这个函数阻止了“重入”调用,所以在其他线程返回之前,没有其他的线程会进入这个函数。 但是,我不明白为什么要这样保护一个单一的function。 恕我直言,所有访问/修改文件指针(代码示例中的_file )的函数都必须受到保护,因此可以成为线程安全的。 这需要围绕整个function块构build一个锁,它实际上调用了标准的C函数fseek和fread,所以我没有看到提供这种非阻塞函数的要点。

有人能解释我这些locking机制,因为我想我们的偏执lockingscheme浪费了一些性能?

先谢谢你!

Solutions Collecting From Web of "_fread_nolock,_fseek_nolock的用途是什么?"

对于一些简单的代码,FILE *中的锁就足够了。 考虑一个基本的日志记录基础结构,您希望所有线程通过一个通用的FILE *进行记录。 内部锁定将确保FILE *不会被多个线程破坏,并且由于每个日志行应该是独立的,所以不会有多个单独的调用交错。

如果您使用Microsoft多线程C运行时,所有需要全局或静态变量的函数将会正常工作(如printf和fread,不要问我为什么需要全局变量)。 但是,您仍然无法将FILE *结构传递给写入它的函数,并期望它是线程安全的。

所以微软的“线程安全”功能只有在它们是可重入的意义上才是线程安全的,即所有对全局和静态的访问都是通过互斥锁或类似的方法完成的。 但不是在这个意义上,你可以用同一个FILE *同时调用两个fprintf()。

资料来源: http : //msdn.microsoft.com/en-us/library/1bh5ewb2%28VS.71%29.aspx

如果您的应用程序已经保证对文件句柄的序列化访问,那么如果您告诉c运行时绕过它自己的序列化,则可以获得更好的性能。 这是_fread_nolock等功能的目的。