Nun wurde das ganze bewertet und ich habe ein paar Rückmeldungen bekommen über Fehler, die ich gemacht habe, die ich aber selbst nicht nachvollziehen kann (wie das beim Threading ja leider öfter ist). Hier mal meine Lösung(C++11):
Code: Alles auswählen
#include <iostream>
#include <thread>
#include <condition_variable>
#include <string>
using namespace std;
mutex m;
condition_variable cond;
bool ready;
const string ping = "Ping!";
const string pong = "Pong!";
void Ping(){
for(int i=1;i<=3;i++)
{
lock_guard<mutex> lck(m);
cout << ping << endl;
ready=true;
cond.notify_one();
}
}
void Pong()
{
for(int i=1;i<=3;i++)
{
unique_lock<mutex> lck(m);
cout << pong << endl;
cond.wait(lck, [] {return ready;});
}
}
int main()
{
cout << "Ready... Set... Go!" << endl;
thread t1(Ping);
thread t2(Pong);
t1.join();
t2.join();
cout << "Done!" << endl;
cin.get();
return 0;
}
Natürlich wird bei mir immer Ping! Pong! ausgeführt und nicht mehrere Pings oder Pongs nacheinander.You have a deadlock and the threads are not correctly synchronized. Because Ping it can be executed several times before Pong so the messages wouldn't alternate. Occasionally Ping could be executed three times and finished before Pong, it causes a deadlock.
Ich hab es sogar auf 300000 gesetzt und natürlich kein Ping! Ping! bekommen.Unfortunately implementation has an error in using synchronization primitives. I set iteration count to 3000 and execute the program on dual-core cpu, and got the such result: ".. Ping! Pong! Ping! Ping! [stop] ". I suppose the reason is Ping thread doesn't check the condition variable (just set it) and also Pong thread just after successfully finished waiting on condition variable release the mutex while moving to the next for() iteration.
Ok, das gleich als irrelevant einzustufen, ist schon hartincrease the number of iterations - it prints "Ping!Ping!Ping!Ping!Ping!Pong!Ping!Pong!Ping" - that is erroneous. I consider this solution as irrelevant.

Also zu meiner Frage: Kennt sich jemand mit den Synchronisationsprimitiven von C++11 aus und kann mir meinen Fehler sagen? Die trivialen Tutorial-Beispiele, die es dazu im Netz gibt, helfen mir aktuell nicht weiter. Kann es wirklich an der Bedingungsvariable liegen oder habe ich vielleicht die wait()-Methode falsch verstanden/eingesetzt?
Eigentlich dachte ich der Ablauf wäre so:
Der Ping-Thread sperrt über den Lock und führt Ping aus, setzt ready auf true und informiert eventuell wartende Threads. Anschließend wird der lock gelöst. Ein Pong Thread holt sich den lock und wird durch wait dann wieder schlafen gelegt, bis ready erneut true ist. Und ich sehe gerade, ich setze ready nicht auf false. Kann da der Fehler liegen?