Ich möchte etwas über Mutex und Semaphor wissen.
Meine Frage ist,
Wenn ein Thread versucht, eine Sperre für einen Mutex zu erhalten, wenn dieser Mutex bereits gehalten wird, verwendet er normalerweise einen Aufruf an den Betriebssystemkern, um anzuzeigen, dass er wartet und dann, wenn der Thread, der die Sperre aktuell hält, entsperrt der Mutex wird dann einen Aufruf an den OS-Kernel machen, einen der wartenden Threads zu wecken.
Dasselbe gilt für ein Semaphor, außer dass es nur blockiert, wenn der Zählerwert unter Null verringert wird, und Threads nur dann aufgeweckt werden, wenn der Zählerstand wieder über Null ansteigt.
Ein besetztes Warten ist, wo Sie nicht blockieren oder schlafen, wenn Sie auf etwas warten, sondern wiederholt in einer Schleife abfragen, so dass der Prozessor immer beschäftigt ist, aber nichts Nützliches tut.
Um wirklich eine "busy wait" zu erreichen, benötigen Sie eine atomare Variable, aber POSIX-Threads bieten so etwas nicht, so dass Sie in pthreads nicht wirklich ein busy wait schreiben können. Der nächste, den Sie bekommen können, ist einen Mutex zu sperren, ein Flag zu lesen, den Mutex zu entsperren, eine Schleife, wenn das Flag nicht gesetzt wurde. Dies sperrt und entsperrt den Mutex wiederholt, wartet jedoch nicht auf die Daten bereit sein. In diesem Fall sollten Sie stattdessen eine Bedingungsvariable verwenden.
Normalerweise sagen Sie, dass ein Thread schläft, wenn er so etwas wie usleep
aufgerufen hat, um seine eigene Ausführung für einen bestimmten Zeitraum zu unterbrechen. Dies ist im Gegensatz zum Blockieren, wo es auf ein bestimmtes Signal wartet, das von einem anderen Thread bereitgestellt wird.
Bitte sehen Sie sich an: Ссылка
Ja, sowohl mutex als auch Semaphor synchronisieren Kernel-Objekte, die, wenn ein Thread versucht, zu erhalten ihnen wird dieser Thread auf schlafen gelegt , wenn das Objekt bereits einem anderen Thread gehört.
Wie Sie bereits vermutet haben, ist dieses schlafende ein entscheidendes Feature, da es anderen Threads erlaubt, mehr nützliche Arbeit zu leisten, als nur 'Looping / Polling'.
Das schlafende dieser Threads endet, wenn der Thread, dem das Objekt zugewiesen ist, es ablegt.
[ OS Scheduler gibt keinen slice für schlafende Threads ].
Vergleichen Sie es mit einer Sperre & amp; Spinlock , in dem sich ein Thread im Status "Schleife / Besetzt / Warten" befindet und wertvolle CPU-Zeit verschwendet, die fast nichts ist. Daher sollten Spinlocks im Benutzercode vermieden werden. Verwenden Sie stattdessen einen kritischen Abschnitt , Mutex oder Semaphore .
Wie Sie aus dem obigen Link sehen können, sind beide Objekte unterschiedlich und sollten im richtigen Kontext verwendet werden, der am besten passt.
Stellen Sie sich einen Mutex als Sperre vor, der nur einen Thread erlaubt. Und dass es viele sichere Attribute (Besitz, Kündigung, Rekursion, etc.) Hat.
Und denken Sie an einen Semaphor als Sperre , der nur eine bestimmte Anzahl von Threads zulässt es. Es hat jedoch nicht die vielen nützlichen Attribute eines mutex .
Hoffe, das hilft.
Das hängt vom Typ des Mutex (seiner Backing-Implementierung) ab, einige sind beschäftigt, sich mit Back-Off zu drehen, andere schlafen nur das Kernthread-Objekt, das später beim Aktualisieren des Mutex und einigen davon hybrid wird die beiden (Valves Source-Engine verwendet die hybriden). Seine Eigenschaften hängen auch davon ab, wann und wie oft Kernel / Userspace-Barrieren überschritten werden müssen, da dies manchmal kostspieliger sein kann, als sich nur ein wenig zu drehen (siehe dies , wenn Sie mehr in die Spinning vs Schlafseite der Dinge bekommen wollen) .
Mutexes sind im Allgemeinen für einzelne Thread-Einträge gleichzeitig (obwohl sie rekursive Einträge durch denselben Thread unterstützen können). Semaphore andererseits erlauben nur n Threads gleichzeitig, um sie zu erfassen (siehe hierzu MSDN Writup oder dies vergleichende Intel-Write-up).
Das Schlummern eines Threads bedeutet im Allgemeinen, dass er seine Zeitschlitzzuweisung für die Zuweisung aufgibt, bis er bereit zum Aufwachen ist, und der OS-Scheduler gibt ihm eine weitere Zeitscheibe. Die besten Beispiele, die Sie wahrscheinlich finden werden, wären tatsächlich in der Linux-Kernel-Quelle (oder einem anderen Open-Source-Betriebssystem).
- Was Mutex tatsächlich tut, wenn ein Thread versucht, in eine von einem Mutex gesperrte Region einzutreten, a. es wartet auf die Freigabe des Schlosses? oder b. es geht zu schlaf, bis das Schloss freigegeben ist. In diesem Fall wacht es wieder auf Wann wird die Sperre aufgehoben?
Wenn ein Thread versucht, eine Mutex-Sperre zu erhalten, bleibt er stecken und kehrt nur zurück, wenn die Sperre für diesen Thread erteilt wurde. Die Sperre wird von OS erkannt, also weiß OS, dass eine solche Sperre verfügbar ist, um Thread zu geben - es hat nichts anderes zu tun. Der Thread ist im Betriebssystem geparkt. Es ist nur das Betriebssystem, das weiß, dass jetzt der Thread das Eigentum hat, dass er wieder einschläft. In einem einzelnen CPU-System, wenn gerade ein anderer Prozess aktiv ist, kehrt die Mutex-Sperre nur dann zurück, wenn der Thread beides hat - CPU verfügbar und Sperre erteilt!
Hinweis: Wenn Sie fwrite
oder select
ausführen, passiert dasselbe. Da OS weiß, dass die jeweilige IO Zeit braucht, wird der Thread inaktiv. Wenn Daten eintreffen, wird der Thread ausführbar.
- Gleiche Frage wie 1, aber in diesem Fall ist es Semaphor. Kannst du mir einen Code bezüglich beschäftigtem Warten in Pthread in C geben, und auch einen Fall? wo Thread in den Schlaf geht statt zu warten? bedeutet Schlaf, dass es ist blockiert oder schlafen ist eine andere Art von beschäftigtem Warten?
In beiden Fällen gibt es KEIN Wartezeiten. Wenn jemand damit beschäftigt wäre, die Zeit zu verlieren, bis Sie die Sperre bekommen - Sie haben tatsächlich den Zweck der Sperre verfehlt! Betrachten wir das, sagen wir, wir haben streng eine einzelne CPU (und ein dummes Betriebssystem). Was nun passiert, ist, Thread 1 versucht, eine Sperre zu erhalten, da die Sperre bei Thread B liegt, so dass Thread A beginnt, beschäftigt zu arbeiten. Daher wird die CPU niemals aus Thread A freigegeben und Thread B bekommt niemals die Chance, auf der CPU ausgeführt zu werden - am Ende sind beide Threads in einer nutzlosen Situation. Sperren führt auf dem Thread-Objekt nichts aus. Beim Sperren werden die Threads immer gesperrt
Warten, schlafen, blockieren, alle bedeuten das Gleiche:
Der Thread führt einen Systemaufruf durch (erhalte einen Mutex oder Semaphor, warte einige Zeit, was auch immer)
Das Betriebssystem übernimmt die Kontrolle, führt den Scheduler aus, markiert den Thread als Warten auf eine Ressource, aktualisiert auch den Status anderer Threads und gibt einem Thread dann die Steuerung, der zur Ausführung bereit ist. Wenn mehr als ein Thread zur Ausführung bereit ist, wird einer entsprechend der Zeitplanungsrichtlinie ausgewählt.
Sobald die Ressource verfügbar gemacht wird (durch einen anderen Systemaufruf eines anderen Threads), aktualisiert der Scheduler den Status des vorherigen Thread vom Warten auf eine Ressource bis zur Ausführung und der Thread erhält die Kontrolle über sobald die Scheduler-Richtlinie dies beschließt.
Solange der Thread auf eine Ressource wartet, verbraucht er keine CPU. Es gibt keine Umfrage von seinem Teil.
In einfachen Worten Mutex ist für das Zeug, wenn Sie sich mit 1 Schloss beschäftigen .... Semaphor ist für mehrere Schlösser .. Ich werde versuchen, Ihnen die Proben zu senden. Ich erinnere mich, dass ich einige Aufgaben in Bezug auf Semaphore und Mutex in C hatte. Was das Konzept betrifft, ist das hier etwas Lustiges Ссылка :)
Danke
Tags und Links c multithreading pthreads mutex semaphore