pthread_cond_wait ohne Mutex
-
Hey Leute,
ich beschäftige mich gerade etwas mit Pthreads und dabei derzeitig mit der Funktion "pthread_cond_wait".
Ich verstehe nicht so ganz, warum diese zwingend an einen Mutex gebunden ist.
Ich kann zwar alle Beispiele gut nachvollziehen, indem ein Mutex gebraucht wird (Warteschlangen mit Consumer-Producer etc.) und verstehe auch vollkommen den Sinn dahinter, aber was ist mit Beispielen die Beispielsweise keinen Mutex benötigen (da es nicht zu kritischen Abschnitten kommt).
Der Mutex wird selbst in der Doku damit begründet, dass vor "pthread_cond_wait" stets eine zu überprüfende Bedingung steht und diese durch den Mutex geschützt werden muss. Dies ergibt auch Sinn, aber es muss doch auch Beispiele geben, in der vor "pthread_cond_wait" keine Bedingung zu überprüfen ist und der Mutex somit redundant wäre oder?Beste Grüße
-
MatheStein schrieb:
Dies ergibt auch Sinn, aber es muss doch auch Beispiele geben, in der vor "pthread_cond_wait" keine Bedingung zu überprüfen ist und der Mutex somit redundant wäre oder?
In solchen Beispielen ist eine Condition Variable dann vielleicht einfach nicht unbedingt das Mittel der Wahl!? Der Mutex ist außerdem wichtig zur Vermeidung von Race Conditions wo der Thread dann nie wieder aufgeweckt würde etc.
-
Danke für deine Antwort
Du hast recht, "pthread_cond_wait" sollte stets (wie das "cond" schon andeutet) mit einer Bedingung verknüpft sein. In der Regel sind das auch meist irgendwelche booleschen Ausdrücke, die vorab mit "if" oder "while" überprüft werden und dann entsprechend an die zugehörigen Bedingungsvariable weitergegeben.
Hierzu habe ich auch schon direkt eine Frage und zwar hätte man in C die Möglichkeit boolesche Ausdrücke als ein Datentyp zu erfassen, dann würde man "pthread_cond_wait" eigentlich lieber direkt den boolschen Ausdruck übergeben wollen, anstatt den Umweg mit der Bedingungsvariable zu gehen oder? Man geht diesen Umweg nur, weil man diese Möglichkeit nicht hat oder?--------------------------------------------------------------------------
Was ist weiterhin mit dem Fall, dass die entsprechende Bedingung auf die gewartet wird kein boolescher Ausdruck etc ist.
Betrachte man hierzu Beispielsweise zwei Threads T_1 und T_2 und möchte diese an einem Punkt synchronisieren, von dem man aus irgendeinem Grund genau weiß, dass T_1 ihn eher erreichen wird als T_2, dann könnte man in T_1 einfach an entsprechender Stelle ein "pthread_cond_wait" aufrufen und entsprechend in T_2 ein "pthread_cond_signal" und ein Mutex wäre hier gar nicht nötig oder?
(In diesem Fall wäre die Bedingung, dass T_2 einen bestimmten Programmpunkt erreicht)Grüße
-
Das gibt es und es heißt
pthread_barrier_t
.
-
Danke, in diesem Fall ist eine Barriere sicher besser, das Ganze war aber eher als Beispiel gedacht für einen Fall, wo die Bedingung für eine "pthread_cond_wait" gerade kein boolescher Ausdruck ist und für diese ein Mutex evtl. nicht von Nöten sein sollte, etwas sinnvolleres ist mir auf die Schnelle leider nicht eingefallen.
-
Vielleicht auch anders gefragt, gibt es kein "normales" signal/wait in pthreads, d.h. Signalisierungskonzepte, welche an keine Bedingung geknüpft sind?
-
MatheStein schrieb:
dann könnte man in T_1 einfach an entsprechender Stelle ein "pthread_cond_wait" aufrufen und entsprechend in T_2 ein "pthread_cond_signal"
Dein Gedanke ist grundsätzlich schon richtig. Ist aber mit dem Pthreads-Konstrukt der Conditionvariable so nicht zu implementieren. Einmal natürlich weil pthread_cond_wait zwingend mit einem gelockten Mutex aufgerufen werden muss. Aber selbst wenn wir das ignorieren, geht es nicht: pthread_cond_wait ist so definiert, dass einem Aufwachen nicht zwingend ein entsprechender signal-Aufruf zugeordnet sein muss. Ein signal-Call kann (nicht muss!) durchaus auch mehrere Threads wecken. cond_wait kann auch zurückkehren ohne dass irgendjemand überhaupt signal aufgerufen hat. Dieses Konzept nennt man "spurious wakeups" und ist ein Grund dafür, dass man cond_wait praktisch nur in einer Schleife korrekt nutzen kann, die nach dem Aufwachen überprüft, ob die Bedingung zum Weitermachen wirklich erfüllt ist oder ob dein Thread wieder schlafen gehen soll. Letztendlich musst du die Nutzung einer Pthreads-Conditionvariable also an eine Bedingung knüpfen.
Vielleicht auch anders gefragt, gibt es kein "normales" signal/wait in pthreads, d.h. Signalisierungskonzepte, welche an keine Bedingung geknüpft sind?
Semaphoren sind dir ein Begriff? Bei diesen läuft die "Bedingung" zum Schlafen gehen mehr oder weniger darauf hinaus, ob ihr ganzzahliger Wert kleiner 0 würde, wenn du eins von ihm abziehst.
Auf Unix-Systemen findest du in der Regel POSIX-Semaphoren. Diese sind zwar nicht Teil von Pthreads, dürften aber auf praktisch allen Systemen verfügbar sein, auf denen es auch Pthreads gibt. Siehe auch die Manpage sem_overview(7).
Mit Semaphoren kannst du Mutexes und Conditionvariablen implementieren. Gleiches gilt übrigens auch umgekehrt: mithilfe eine Mutexes und einer Conditionvariable lässt sich ein Semaphor bauen. Ist eine nette kleine Übung und solltest du vielleicht mal machen, wenn dich sowas interessiert.
-
Wenn du sowas wie CreateEvent, Set/ResetEvent oder Waitfor Object suchtst, ja kann mit pthread, mutex und condition variable nachgebaut werden.