Aufgaben

  1. C++11 Thread Variablenübergabe
    Im besprochenen Beispielprogramm zu threads wird die Variable accum als globale Variable definiert, was als schlechter Programmierstil gilt. Besser ist es, diese Variable als Parameter zu übergeben. Ändern Sie das Beispielprogramm, indem Sie einen Parameter int& accum zu square hinzufügen. Dies sollte eine Referenz sein, da accum sich ändern lassen sollte. Allerdings kann der Aufruf nicht über thread(&square, accum, i) erfolgen, da dies eine Kopie von accum erzeugt und square mit dieser Kopie aufruft. Verwenden Sie anstatt ref(), d.h. thread(&square, ref(accum), i).

    Lösungsbeispiel: thread_lsg1.cpp (nicht thread safe), thread_lsg1b.cpp (thread safe)

  2. C++11 tasks
    Verwenden Sie anstatt threads den async-Befehl im beschriebenen Programm zur parallelen Berechnung der Summe der Quadarate bis 20. Fügen Sie hierzu die future<int> Objekte zu einem vector<future<int» hinzu. Am Ende des Programms iterieren Sie über alle futures und erhalten den jeweiligen Rückgabewert und fügen diesen zur Gesamtsumme hinzu.

    Lösungsbeispiel: thread_lsg2.cpp

  3. C++11 tasks und this_thread
    Implementieren Sie das C++11 task Beispielprogramm, wie in der vorhergehenden Aufgabe beschrieben. Um festzustellen, ob das Programm tatsächlich parallel ausgeführt wird, versuchen Sie folgendes:

    Lösungsbeispiel: thread_lsg3.cpp

  4. Erzeuger-Konsumenten Problem
    Das Erzeuger-Konsumenten (producer-consumer) Problem ist in einfacher Form ein thread, der Waren erzeugt, und ein weiterer thread, der diese Waren konsumiert. Dabei soll der consumer thread beim Warten eine conditions Variable verwenden. goods.push(i) und good.pop() sollen sich gegenseitig ausschließen, so daß die Daten nicht beschädigt werden. Die Variablen c++ und c- sollen dabei als Kontrolle dienen, da am Ende sich alles zu 0 addieren sollten.

    Führen Sie folgendes Beispiel-Programm aus: tconsumer.cpp.
    Welche Ergebnisse erhalten Sie bei mehrfachem Ausführen ?

    Versuchen Sie das Programm zunächst mit lock-unlock Blöcken zu reparieren und führen das Programm 1000-10000 mal aus, um das Ergebnis zu verifizieren. Versuchen Sie dann, conditions Variablen zu verwenden.

    Lösungsbeispiel: thread_lsg4.cpp

  5. Aufzug Simulation
    Nehmen Sie ein mehrstöckiges Haus an, in dem mehrere Personen arbeiten. Die Personen wechseln gelegentlich die Etagen und benutzen dazu einen 1-Personen Fahrstuhl (also noch kleiner als in Schelling 4 ...). Jede Person soll in einem eigenen Thread simuliert werden, die Arbeit zwischen der Aufzugbenutzung wird durch sleep(some-random-time) simuliert. Aufzugfahren ist eine separate Klasse/Methode, die Fahrzeit wird wiederum mit sleep() proportional zur Distanz simuliert. Mittels Mutex lock()/unlock() kann sichergestellt werden, dass nur eine Person (=Thread) den Aufzug verwendet. Ausgabe der Aktionen auf stdout.

    Studieren Sie den Einfluss von Zahl der Stockwerke, Zahl der Beschäftigten, u.a., auf den Durchsatz.

    Einfaches Beispielprogramm: AufzugSimCpp11.cpp (mit C++11 threads) bzw. AufzugSim.cpp (mit QThreads).


  6. (Projekt) Primzahl-Finder Multi-Threaded
    Ein einfaches Programm zum Finden von Primzahlen prime_simple.C soll so abgeändert bzw. erweitert werden, so daß die Suche verteilt und unabhängig auf verschiedenen Zahlenbereichen durchgeführt werden kann.

  7. OpenMP Beispiel zur Berechnung von Pi
    PiOMP.cpp ist ein kleines Programm das Pi über Zufallszahlen berechnet und OpenMP zur Parallelisierung verwendet.

    Versuchen Sie es nachzuvollziehen.

    Wozu braucht man # pragma omp critical?

    Warum benutzt man drand48_r und srand48_r( ...) ?

    Modifizieren Sie das Programm und verwenden statt OpenMP C++11 tasks bzw async.


GDuckeck 2019-08-01