Mutex

Ein sog. mutex (mutal exclusion) erlaubt es, Programmblöcke einzuschliessen, die nur in einem thread gleichzeitig ausgeführt werden dürfen. Vorheriges Beispiel sollte also folgendermaßen erweitert werden:


#include <iostream>
#include <vector>
#include <thread>
using namespace std;

int accum = 0;
mutex accum_mutex;

void square(int x) {
    int temp = x * x;
    accum_mutex.lock();
    accum += temp;
    accum_mutex.unlock();
}

int main() {
    vector<thread> ths;
    for (int i = 1; i <= 20; i++) {
        ths.push_back(thread(&square, i));
    }

    for (auto& th : ths) {
        th.join();
    }
    cout << "accum = " << accum << endl;
    return 0;
}

Die vorher aufgetretene ``race condition'' ist somit behoben. Der erste thread erhält den sog. lock nach dem Aufruf von lock(). Währenddessen warten alle anderen threads, die lock() aufgerufen haben, bis der lock des mutex aufgehoben ist. Im Programmbeispiel ist es wichtig, die zusätzliche Variable temp einzuführen, das die Berechnung von x*x außerhalb des lock-unlock-Block stehen sollte, da anderenfalls der lock blockiert wird, während die zeitintensiven Berechnungen ausgeführt werden.

Das Vermeiden von race conditions bzw. das Verwenden von locks ist ziemlich heikel. Insbesondere bei Verwendung von mehreren locks kann man leicht in eine dead-lock Situation kommen.

Image trafficDeadlock




GDuckeck 2019-08-01