2016-03-30 34 views
1

HDF5スレッドセーフライブラリの使用に関する質問があります。
私は現在、"HDF5_ENABLE_PARALLEL""HDF5_ENABLE_THREADSAFE"のオプションを使用して私の同僚によってコンパイルされたHDF5 C++ライブラリ(静的)のインスタンスを扱います。HDF5スレッドセーフライブラリの使用

私がしようとするのは、複数のスレッドを使用していくつかのデータを含む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ファイルを扱うことができます。
ライブラリー自体は、一度に1つのスレッドしかファイルにアクセスしていない(またはAPI呼び出しを行っている)ことを確実にする必要がありますか?
ライブラリを再コンパイルすると、C++ APIを使用することはできますか?

また、ミューテックスを使用してAPI呼び出しをロックしようとしましたが、まだいくつか問題がありました。

ここに誰かが私に私の問題の答えを与えることができたらとても感謝します。 私は十分に自分自身を説明してくれることを願っています。これは少し長いが残念です;)。

ありがとうございます。

+0

このファイルを変更する必要はありますか?そうでなければ、各スレッドでファイルを開こうとすることができます。つまり、 'H5File t_file(FILENAME、H5F_ACC_RDONLY);を' read_row() 'に移動します。 –

+0

とにかく '--enable-threadsafe'設定オプションに頼るのは危険です。実際にはどういう意味ですか?これにより、HDF5ライブラリのソースコード内でロック機構が有効になります。しかし、このロック機構は特定のスレッディング・パディングに依存しています。これはPthreadsライブラリですが、C++ 11スレッドを使用しています(おそらくPthreadsにも組み込まれています)。異なるスレッドのパラダイムを混在させることは非常に脆弱であり、一般的には推奨されません。同じ理由から、HDF5はOpenMPと一緒に使用することはお勧めしません。 –

+0

@DanielLangrいいえファイルを変更するつもりはないので、H5Fileオブジェクトをスレッドに移動することが解決策になるかもしれません。私は上記の例でこれを試しました。悲しいことに、以前のクラッシュは予期せず発生していたので、私は確信が持てません。しかし、私はこのような形で図書館を使うかもしれないと思う。スレッドセーフで、実際のIOを行うラッパーは1つだけです。このラッパーは、複数のワーカースレッドで使用することができます。私はこれがうまくいくと思います。返信いただきありがとうございます。 – YoLieR

答えて

1

HDF5 documentationによれば、--enable-threadsafeでコンパイルすると、スレッドセーフティの第1レベルを提供します。しかし、これはCライブラリの場合にのみ当てはまります。高水準のC++ライブラリはスレッドの安全性をサポートしていません。あなたが実行しようとする場合は、

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

あなたが遭遇するでしょう。 C++を使いたい場合は、 "--enable-threadsafe"オプションを指定せずにhdf5をコンパイルする必要があります。同時に、異なるスレッドからhdf5ライブラリにアクセスすることは絶対に避けてください。私の経験から、常にC++の同じスレッドからHDF5にアクセスする方が良いです。

一部のLinuxディストリビューションでは、--enable-threadsafe--enable-cxxの両方を有効にして、この制限を「修正」するパッチを適用して、C++ライブラリを効果的に破棄しています。 libhdf5の新しいバージョンでも、パッチなしで可能になるオプション--enable-unsupportedがあります。このような "改良" hdf5パッケージを使用すると、ランダムクラッシュが発生します。したがって、もしあなたがそのような "改善された"ライブラリを得ていないかどうかを確認し、必要に応じて手動で再コンパイルしてください。

関連する問題