c++ - 使用 HDF5 线程安全库

标签 c++ thread-safety hdf5 hdf

我有一个关于使用 HDF5 线程安全库的问题。
我目前使用 HDF5 C++ 库(静态)的一个实例,该实例由我的一位同事使用 "HDF5_ENABLE_PARALLEL""HDF5_ENABLE_THREADSAFE" 选项编译.

我尝试做的是使用多线程访问包含一些数据的 HDF 文件。数据的实际读取不需要并行。

我的代码目前看起来像这样简化了:

// includes etc.

int main() {

  H5File t_file(FILENAME, H5F_ACC_RDONLY);

  thread t1(read_row, cref(t_file), 0);
  thread t2(read_row, cref(t_file), 1);

  t1.join();
  t2.join();

  return 0;

}

void read_row(const H5File & p_file, size_t p_row){

  double data[DIM_Y][DIM_X];

  try {

    DataSet t_dataset = p_file.openDataSet("/Group0/Set0");
    DataSpace t_dataspace = t_dataset.getSpace();

    hsize_t dims[2];
    auto status = t_dataspace.getSimpleExtentDims(dims, nullptr);


    hsize_t count[2] = { 1, DIM_X };
    hsize_t offset[2] = { p_row, 0 };
    t_dataspace.selectHyperslab(H5S_SELECT_SET, count, offset);

    hsize_t mem_dim[2] = { 1, DIM_X };
    DataSpace t_memspace(RANK, mem_dim);
    hsize_t mem_offset[2] = { 0, 0 };
    t_memspace.selectHyperslab(H5S_SELECT_SET, count, mem_offset);

    t_dataset.read(data, PredType::NATIVE_DOUBLE, t_memspace, t_dataspace);

  }
  catch (...){
    cout << "Caught some exception" << endl;
  }
}

代码可以编译,如果我在大部分时间运行程序,一切都会顺利。
但是有时我会收到以下错误消息:

HDF5-DIAG: Error detected in HDF5 (1.8.16) thread 0:
  #000: D:\Projects\CANoe\90\CMake-hdf5-1.8.16\hdf5-1.8.16\src\H5D.c line 358 in H5Dopen2(): not found
    major: Dataset
    minor: Object not found
  #001: D:\Projects\CANoe\90\CMake-hdf5-1.8.16\hdf5-1.8.16\src\H5Gloc.c line 430 in H5G_loc_find(): can't find object
    major: Symbol table
    minor: Object not found
  #002: D:\Projects\CANoe\90\CMake-hdf5-1.8.16\hdf5-1.8.16\src\H5Gtraverse.c line 861 in H5G_traverse(): internal path traversal failed
    major: Symbol table
    minor: Object not found
  #003: D:\Projects\CANoe\90\CMake-hdf5-1.8.16\hdf5-1.8.16\src\H5Gtraverse.c line 596 in H5G_traverse_real(): can't look up component
    major: Symbol table
    minor: Object not found
  #004: D:\Projects\CANoe\90\CMake-hdf5-1.8.16\hdf5-1.8.16\src\H5Gobj.c line 1139 in H5G__obj_lookup(): can't check for link info message
    major: Symbol table
    minor: Can't get value
  #005: D:\Projects\CANoe\90\CMake-hdf5-1.8.16\hdf5-1.8.16\src\H5Gobj.c line 333 in H5G__obj_get_linfo(): unable to read object header
    major: Symbol table
    minor: Can't get value
  #006: D:\Projects\CANoe\90\CMake-hdf5-1.8.16\hdf5-1.8.16\src\H5Omessage.c line 896 in H5O_msg_exists(): unable to release object header
    major: Object header
    minor: Unable to unprotect metadata
  #007: D:\Projects\CANoe\90\CMake-hdf5-1.8.16\hdf5-1.8.16\src\H5O.c line 1963 in H5O_unprotect(): unable to release object header
    major: Object header
    minor: Unable to unprotect metadata
  #008: D:\Projects\CANoe\90\CMake-hdf5-1.8.16\hdf5-1.8.16\src\H5Gobj.c line 1524 in H5O_msg_exists(): H5G__obj_get_linfo
    major: Object cache
    minor: Unable to unprotect metadata
  #009: D:\Projects\CANoe\90\CMake-hdf5-1.8.16\hdf5-1.8.16\src\H5C.c line 5281 in H5C_unprotect(): Entry already unprotected??
    major: Object cache
    minor: Unable to unprotect metadata

我怀疑发生这种情况是因为库本身在其当前形式下不是线程安全的。

我现在的问题是:
如果我使用 --enable-threadsafe 选项重新编译库,那么我是否能够像上面那样处理 HDF5 文件。
库本身应该确保一次只有一个线程访问文件(或进行 API 调用)对吗?
如果我重新编译这个库,我还能使用 C++ API 吗?

我也尝试过使用互斥锁来锁定 API 调用,但我仍然遇到了一些问题。

如果有人能回答我的问题,我将不胜感激。 我希望我对自己的解释足够好。对不起,如果这有点长;)。

提前致谢。

最佳答案

根据 HDF5 documentation ,它在使用 --enable-threadsafe 编译时提供第一级线程安全。但这仅适用于 C 库。高级 C++ 库不支持线程安全。如果你将尝试运行

./configure --enable-threadsafe --enable-cxx 

你会得到一个错误。 所以,如果你想使用 C++,你必须在没有“--enable-threadsafe”选项的情况下编译 hdf5,你不应该同时从不同的线程访问 hdf5 库。根据我的经验,最好始终从 C++ 中的同一线程访问 HDF5。

某些 Linux 发行版应用了一个补丁,通过允许 --enable-threadsafe--enable-cxx 来“修复”此限制,从而有效地破坏了 C++ 库。较新版本的 libhdf5 甚至有一个选项 --enable-unsupported,这将允许它没有补丁。使用这样一个“改进”的 hdf5 包,您会遇到随机崩溃。因此,请检查您是否没有获得此类“改进的”库,并在需要时手动重新编译它。

关于c++ - 使用 HDF5 线程安全库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36308176/

相关文章:

c++ - libpqxx 库中没有 pqxx::tuple 吗?

c++ - 敌人不会跟随玩家。 SDL2/C++

用于设置核心亲和性的 C++ 风格?

c++ - test.cpp :(. text._ZN1AC2Ev[_ZN1AC5Ev]+0x8)||对 `vtable for A' 的 undefined reference |

matlab - 使用 h5py 读取 matlab .mat 文件

python - pandas - 如何仅将 DataFrame 的选定列保存到 HDF5

python - 由于 hdf5 错误,无法安装库

java - 从 ConcurrentMap.remove() 获取键是否存在

java - 调用wait()方法后锁被释放?

java - 如果一个方法不使用对象的字段那么它是线程安全的吗?