================================ Synchronisierung mit den Workern ================================ Die Synchronisierung mit der Beendigung eines Threads war möglich mit Hilfe der Methode `join`. Da bei einem Thread-Pool die Threads nach der Fertigstellung eines Auftrags sich mit anderen Aufgaben beschäftigen, fehlt hier eine wichtige Synchronisierungsmöglichkeit. Wir können momentan nicht ohne weiteres darauf warten, dass eine Aufgabe beendet ist. Das Problem lässt sich jedoch mit einer Hilfsklasse lösen, die mit einer Mutex- und Bedingungsvariablen arbeitet: ---- CODE (type=cpp) ---------------------------------------------------------- struct JobStatus { public: JobStatus() : finished(false) { } void is_finished() { std::unique_lock lock(mutex); assert(!finished); finished = true; cv.notify_all(); } void wait() { std::unique_lock lock(mutex); if (!finished) { cv.wait(lock); } } private: std::mutex mutex; std::condition_variable cv; bool finished; }; ------------------------------------------------------------------------------- Sowohl das den Auftrag repräsentierenden Funktionsobjekt als auch der Auftraggeber haben Zugriff auf ein solches Objekt. Das Funktionsobjekt ruft die Methode `is_finished` auf, sobald es fertig ist. Der Auftraggeber kann sich dann mit Hilfe von `wait` synchronisieren. So könnte ein triviales Beispiel aussehen: ---- CODE (type=cpp) ---------------------------------------------------------- ThreadPool pool(2); JobStatus hello; pool.submit([&]() { printf("Hello!\n"); hello.is_finished(); }); hello.wait(); printf("Job appears to be finished!\n"); ------------------------------------------------------------------------------- Aufgabe ======= Schreiben Sie eine Template-Funktion zum Initialisieren einer Matrix, die als zusätzlichen Parameter eine Referenz auf einen Thread-Pool erhält und die die Matrix `A` zweidimensional in Teilblöcke $\mathbf{A}_{i,j}$ zerlegt und die Initialisierung der einzelnen Teilblöcke dem Thread-Pool überlässt. Die maximale Größe der Teilblöcke ist dabei als Parameter zu übergeben. Die Funktion sollte erst dann zurückkehren, wenn die Initialisierung vollständig abgeschlossen ist. Die Vorlesungsbibliothek einschließlich der Matrixklassen steht Ihnen unter _/home/numerik/pub/hpc/session16_ zur Verfügung. Als Vorlage können Sie die letzte Fassung aus der letzten Session verwenden: :import:session15/random_init12.cpp :navigate: up -> doc:index back -> doc:session16/page04 next -> doc:session16/page06