什么';什么是fread nolock和Seek 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;}

什么';什么是fread nolock和Seek 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;},c++,windows,multithreading,fread,fseek,C++,Windows,Multithreading,Fread,Fseek,Out程序使用OpenMP进行多线程处理,多个线程同时访问同一文件。为了避免多线程导致的问题,我们始终在OpenMP关键语句中介绍函数调用: #pragma omp critical { load(...); } P>我知道微软Visual C++运行时包含了如下几个函数,如:代码>例如,\u fread\u nolock()函数描述为 此函数是fread的非锁定版本。它与fread相同,只是不受其他线程的干扰。它可能更快,因为它不会产生锁定其他线程的开销。仅在线程安全上下文(如单线

Out程序使用OpenMP进行多线程处理,多个线程同时访问同一文件。为了避免多线程导致的问题,我们始终在OpenMP关键语句中介绍函数调用:

#pragma omp critical {
    load(...);
}
<> P>我知道微软Visual C++运行时包含了如下几个函数,如:代码>例如,
\u fread\u nolock()
函数描述为

此函数是fread的非锁定版本。它与fread相同,只是不受其他线程的干扰。它可能更快,因为它不会产生锁定其他线程的开销。仅在线程安全上下文(如单线程应用程序)或调用作用域已处理线程隔离的情况下使用此函数

现在我的问题是:我知道函数会阻止“重入”调用,所以在其他线程返回之前,没有其他线程会进入函数。然而,我不理解为什么有必要以这种方式保护单个功能。IMHO必须保护所有访问/修改文件指针的函数(代码示例中的
\u file
),从而使其成为线程安全的。这需要在整个函数块周围构建一个锁,实际调用标准C函数fseek和fread,因此我不认为提供这种非阻塞函数有什么意义

有人能给我解释一下这些锁机制吗?因为我想我们的偏执锁方案浪费了一些性能


提前谢谢你

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

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


来源:

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

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


来源:

对于一些简单的代码,文件*中的锁就足够了。考虑一个基本的日志记录基础结构,您希望所有线程通过一个公共文件*进行日志记录。内部锁将确保文件*不会被多个线程损坏,并且由于每个日志行都应该独立,因此不管各个调用如何交错。

对于一些简单的代码,文件*中的锁就足够了。考虑一个基本的日志记录基础结构,您希望所有线程通过一个公共文件*进行日志记录。内部锁将确保文件*不会被多个线程损坏,并且由于每个日志行都应该独立,因此单个调用如何交错并不重要。

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

如果您的应用程序已经保证了对文件句柄的序列化访问,那么如果您告诉c运行时绕过它自己的序列化,您可以获得更好的性能。这就是_fread_nolock等函数的用途\u fseek\u nolock。此函数始终需要第二个函数来使用文件指针进行word操作。如果您关心性能并且需要文件操作的原子序列,则需要使用_fseek_nolock。您可以使用_lock_file()/_unlock_file()包围一系列文件操作,以使命令成为文件的原子w.r.t。完成后,可以使用_nolock函数稍微减少开销。好的,这解释了为什么fwrite()会锁定其他线程。AFAIR fwrite()移动文件指针,以便多个线程可以通过反复调用fwrite()将日志消息附加到文件中。我仍然看不出为什么会有
\u fseek\u nolock
。此函数始终需要第二个函数来使用文件指针进行word操作。如果您关心性能并且需要文件操作的原子序列,则需要使用_fseek_nolock。您可以使用_lock_file()/_unlock_file()包围一系列文件操作,以使命令成为文件的原子w.r.t。完成后,就可以使用_nolock函数稍微减少开销。