Frage von otoonormal, 17

Datei schreiben von mehreren Threads ohne blockieren?

Moin!

Wie kann man am besten in einer Klasse mit Hlfe von den Standard-Bibliotheken thread, fstream, etc Dateien schreiben, ohne das die KLasse blockiert bzw Informationen verloren gehen?

Mit mutex würde doch dann das Programm einfrieren oder?

Danke für eure Meinung.

Antwort
von reddox86, 12

Nicht unbedingt...kommt natürlich darauf an wie lange du schreibst, also pack das schreiben in kleine Sequenzen, mach dir dafür eine Funktion, hier mal etwas abstrakt dargestellt:

void writeToFile(FileObject &file, DataObject &data) {
  static MutexObject mutex = new MutexObject(1);
  mutex.p();
  file.writeData(data);
  mutex.v();
}

Ist jetzt wie gesagt sehr abstrakt dargestellt...ich nehme mal an du hast bereits eine Architektur oder sowas, da bringt dir ein konkretes Codebeispiel nicht mehr. Falls gewünscht kann ich das aber noch nachliefern.

Was ich damit aber verdeutlichen will: Du musst den Mutex um das schreiben und nur um das schreiben legen. Also sowas wie:

void MyClass::threadFn1() {
  _writeMutex.p();
  for(uint8_t i=0; i<100; i++) {
    _file.write(new DataObject(i));
    sleep(1000);
  }
  _writeMutex.v();
}

void MyClass::threadFn2() {
  _writeMutex.p();
  for(uint8_t i=0; i<100; i++) {
    _file.write(new DataObject(i));
    sleep(1000);
  }
  _writeMutex.v();
}

 würde ein Thread den anderen blockieren. Folgender Ansatz wäre aber sicher:

void MyClass::threadFn1() {
  for(uint8_t i=0; i<100; i++) {
   writeToFile(_file, new DataObject(i));
   sleep(1000);
  }
}

void MyClass::threadFn2() {
  for(uint8_t i=0; i<100; i++) {
    writeToFile(_file, new DataObject(i));
    sleep(1000);
  }
}

Wenn du komplexere Daten schreiben willst (also Zusammenhänge) muss da u.U. noch ein Mutex drüber, aber ich weiß ja nicht, was du genau willst...

PS: Es könnte sein, dass zumindest ein fstream selber schon Threadsafe ist, da müsste man die Doku in Betracht ziehen.

PPS: Wenn man die Datei selber abstrahiert (so wie hier im Beispiel) könnte man das ja schon so Threadsafe machen und die Funktion FileObject::write(DataObject obj) mit der Funktion writeToFile kombinieren.

Keine passende Antwort gefunden?

Fragen Sie die Community

Weitere Fragen mit Antworten