【发布时间】:2009-12-11 19:48:26
【问题描述】:
我们有一个 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 进行多线程处理,并且多个线程同时访问同一个文件。为了避免由于多线程导致的问题,我们总是在 OpenMP 关键语句中包含函数调用:
#pragma omp critical {
load(...);
}
我知道 Microsoft Visual C++ 运行时包含几个函数,如_fseek_nolock、_fread_nolock、_fwrite_nolock 等等...例如_fread_nolock() 函数被描述为
此函数是 fread 的非锁定版本。它与 fread 相同,只是它不受其他线程的干扰。它可能会更快,因为它不会产生锁定其他线程的开销。仅在线程安全的上下文中使用此函数,例如单线程应用程序或调用范围已处理线程隔离的情况。
现在我的问题是:我知道该函数会阻止“重入”调用,因此在其他线程返回之前没有其他线程会进入该函数。但是,我不明白为什么有必要以这种方式保护单个功能。恕我直言,所有访问/修改文件指针(代码示例中的_file)的函数都必须受到保护,因此必须是线程安全的。这需要围绕实际调用标准 C 函数 fseek 和 fread 的整个函数块构建一个锁,所以我看不出提供这种非阻塞函数的意义。
谁能解释一下这些锁定机制,因为我认为我们偏执的锁定方案会浪费一些性能?
提前谢谢你!
【问题讨论】:
-
我忘了补充一下,我们正在讨论 Microsoft 特定的 C++ 运行时函数
标签: c++ windows multithreading fread fseek