pthread_mutex_unlock: Anderer Thread kommt nicht an die Reihe...
-
Hallo,
ich habe da ein Problem. Mein Programm ist grob so aufgebaut:
Thread 1 erledigt eine Aufgabe, die von Thread 2 durch das Holen des Locks unterbrochen werden soll:while(1) { if(pthread_mutex_trylock(&lock) == EBUSY) break; // tu was... pthread_mutex_unlock(&lock); }
Thread 2:
pthread_mutex_lock(lock); // tu was II...
Die Konstruktion ist so, weil "tu was" nicht mehr ausgeführt werden darf, wenn "tu was II" gemacht wurde, weil sonst das Programm abschmiert. Unter OSX klappt das ganze wunderbar, unter Linux tritt aber ein seltsames Problem auf: Wenn der Thread 2 aufgerufen wurde, blockiert der ewig an dem pthread_mutex_lock in Thread 2, die Schleife in Thread 1 läuft einfach weiter und lässt Thread2 gar nicht zum Zug kommen. Wenn ich hinter pthread_mutex_unlock(&lock) in Thread 1 ein "usleep(100)" einbaue, dann klappt es auch unter Linux. Aber das wäre eine totale Notlösung.
Deswegen meine Fragen:
- Gibt es eine Funktion, die einfach sagt: "Lass mal die anderen Threads ran"?
- Gibt es eine schlankere Lösung für die Problemstellung als die mit den Mutex-Locks?Vielen Dank schonmal
Michael
-
Mit sched_yield kannst du die Kontrolle an andere wartende Threads übergeben.
-
Super, genau richtig! Vielen Dank
-
Athar schrieb:
Mit sched_yield kannst du die Kontrolle an andere wartende Threads übergeben.
Hallo zusammen,
Achtung:
sched_yield gibt die Zeitscheibe für den gesamten Prozess ab.
Als Nebeneffekt kann das zwar das Problem lösen,
aber man 'kauft' sich einen ziemlich fiesen Nachteil damit ein:Wenn gleichzeitig ein anderer Prozess busy läuft,
gibt man viel zu oft die Zeitscheibe für den gesmaten Prozess ab,
was dazu führt das der Durchsatz nicht mehr stimmt und
die Performance drastisch (Faktor 100 und mehr) in den Keller geht.Nicht schön das Ganze.
Schöner wären round robbin mutexe.Ich habe im Grunde das gleiche Problem,
und überlege mir einen solchen mutex selbst zu implementieren.
Das müsste gehen und nicht allzu große Performance und Ressourcen Nachteile haben.
Vieleicht weiß jemand eine andere 'Lösung'.Gruß Frank
-
Gibt es sicher keine elegante (schon vorhandene) Methode, mit der man dieses Problem lösen könnte? Soo ausgefallen und abwegig ist das ja nun nicht...
-
Warum nicht einfach ein Flag?
Thread 1:bool doWork = true; pthread_mutex_lock(lock); while (doWork) { // tu was } pthread_mutex_unlock(lock);
Thread 2:
doWork = false; pthread_mutex_lock(lock); // jetzt habe ich den lock