© Harry Broeders.
Bij deze practicumopgave maken we gebruik van de C++11 standaard library. Je mag daarbij gebruik maken van gcc versie 4.7 of hoger maar ik ga er in deze omschrijving vanuit dat je gebruik maakt van Microsoft Visual C++ 2013 Express Edition. Deze ontwikkelomgeving is in lokaal D1.049 en ook in lokaal D1.052 geïnstalleerd.
Opdracht 3a.Test het in de theorie behandelde programma main.cpp. Voeg nu nog een thread toe aan dit programma. Deze thread moet 40x telkens na 5 ms de boodschap "Hallo" op het scherm zetten en de cursor op het begin van de volgende regel zetten. Pas het programma zodanig aan dat alle 3 de threads dezelfde code (functie) gebruiken. |
Het probleem dat we (opnieuw) gaan analyseren is het zogenaamde producer-consumer synchronisatie probleem.
Het voorbeeld programma bestaat uit 3 threads: 2 producers en 1 consumer. De producers produceren data en zetten dit in een buffer. De consumer leest de data uit de buffer en consumeert deze data. Vanzelfsprekend moet ervoor gezorgd worden dat producers en consumer synchroniseren:
In C++ kun
je alle data en functies van de buffer "inkapselen" in de class
CircularBuffer
. Door een template
te gebruiken kunnen
we een herbuikbaar buffer definiëren dat met elk willekeurig type gebruikt kan
worden. Ook het aantal plaatsen in de buffer kunnen we met behulp van een
template parameter instelbaar maken.
template<typename T, int size> class CircularBuffer { public: CircularBuffer(); void put(const T& t); // schrijf element in de buffer. WACHT als buffer vol is! const T get(); // lees een element uit de buffer. WACHT als buffer leeg is! bool isEmpty() const; // vraag of het buffer leeg is private: // Nog invullen! };
Het multi-threaded testprogramma voor de class CircularBuffer
kun je vinden in de file main.cpp.
Opdracht 3b.Implementeer de class |
De code van de consumer lijkt inefficient:
for (int i = 0; i < 1000; ++i) { char c = b.get(); { unique_lock<mutex> lock(m_cout); cout << c; } }
Het gebruik van de lokale variabele c
lijkt overbodig.
for (int i = 0; i < 1000; ++i) { unique_lock<mutex> lock(m_cout); cout << b.get(); }
Opdracht 3c.Wat is de uitvoer als de lokale variable |