Ich habe eine Frage bezüglich der Verwendung der HDF5 Thread Safe Bibliothek.
Ich arbeite derzeit mit einer Instanz der HDF5 C++ - Bibliothek (statisch), die von einem Mitarbeiter von mir unter Verwendung der "HDF5_ENABLE_PARALLEL"
noch die "HDF5_ENABLE_THREADSAFE"
Optionen kompiliert wurde.Verwenden von HDF5 Thread Safe Library
Was ich versuche, ist der Zugriff auf eine HDF-Datei mit einigen Daten mit mehreren Threads. Das tatsächliche Lesen der Daten muss nicht parallel sein.
derzeit Mein Code sieht irgendwie wie folgt vereinfacht:
// 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;
}
}
Der Code kompiliert und wenn ich das Programm laufen die meiste Zeit alles gut geht.
Manchmal jedoch bekomme ich folgende Fehlermeldung:
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
Ich vermute, dies tritt auf, weil die Bibliothek selbst nicht sicher ist Thread in seiner jetzigen Form.
Meine Frage ist jetzt:
Wenn ich die Bibliothek mit der Option --enable-threadsafe neu kompilieren würde, wäre ich dann in der Lage, mit einer HDF5-Datei wie oben zu arbeiten.
Die Bibliothek selbst sollte dann sicherstellen, dass immer nur ein Thread auf eine Datei zugreift (oder einen API-Aufruf ausführt), richtig?
Und wenn ich die Bibliothek neu kompilieren würde, wäre ich immer noch in der Lage, die C++ API zu verwenden?
Ich versuchte auch, die API-Aufrufe mit einem Mutex zu sperren, aber ich hatte immer noch einige Probleme damit.
Ich wäre sehr dankbar, wenn jemand hier mir eine Antwort auf mein Problem geben könnte. Ich hoffe ich habe mich gut genug erklärt. Tut mir leid, wenn das ein bisschen lang wurde;).
Vielen Dank im Voraus.
Müssen Sie diese Datei ändern? Wenn nicht, können Sie versuchen, die Datei in jedem Thread zu öffnen, d. H. 'H5File t_file (DATEINAME, H5F_ACC_RDONLY); 'in' read_row() 'zu verschieben. –
Wie auch immer, es kann gefährlich sein, sich auf die Konfigurationsoption '--enable-threadsafe' zu verlassen. Was bedeutet es eigentlich?Es wird einen Sperrmechanismus im Quellcode der HDF5-Bibliothek aktivieren. Aber dieser Sperrmechanismus beruht auf einem bestimmten Threading-Paradigmen. Scheinbar ist es die Pthreads-Bibliothek, aber Sie verwenden C++ 11-Threads (die wahrscheinlich auch auf Pthreads aufgebaut sind). Das Mischen verschiedener Threading-Paradigmen ist sehr sehr fragil und wird im Allgemeinen nicht empfohlen. Aus dem gleichen Grund wird empfohlen, HDF5 nicht zusammen mit OpenMP zu verwenden. –
@DanielLangr nein Ich werde die Datei nicht ändern, daher könnte das Verschieben des H5File Objekts in den Thread eine Lösung sein. Ich habe das im obigen Beispiel versucht und bisher scheint es zu funktionieren. Leider sind die Stürze früher sehr unvorhersehbar aufgetreten, daher kann ich mir nicht ganz sicher sein. Aber ich denke, ich könnte die Bibliothek auf diese Weise benutzen. Nur ein Wrapper, der threadsicher ist und der die eigentliche IO ausführt. Und dieser Wrapper kann von mehreren Worker-Threads verwendet werden. Ich denke, das könnte funktionieren. Danke für die Antwort. – YoLieR