2010-08-23 5 views
6

Für mich sieht es jetzt wie funktional Semaphore.WaitOne/Release ist gleich Monitor.Wait/Pulse. Interprozessfähigkeiten überspringen, Geschwindigkeit (ja, Monitor wird verwaltet) andere nicht funktionale Unterschiede, was ist dann wirklich ein Unterschied?Semaphore.WaitOne/Release vs Monitor.Pulse/Warten

Antwort

10

Der Hauptzweck einer Semaphore ist die Kontrolle des Zugriffs auf eine begrenzte Menge von Ressourcen. Der Thread kann an der Beschaffung von Ressourcen teilnehmen, indem er WaitOne und Release aufruft. Ein Thead sollte WaitOne aufrufen, um die Ressource zu erwerben. Es wird jedoch nur blockiert, wenn die Zählung der Semaphore 0 erreicht, andernfalls kann der Thread sofort erfassen. Sobald dieser Thread beendet ist, sollte er Release anrufen, um dem Semaphor zu signalisieren, dass ein zusätzlicher Slot für einen anderen Thread freigegeben wurde.

Monitor.Wait und Monitor.Pulse sind drastisch anders. In erster Linie wird nicht gezählt. Wenn Pulse in Abwesenheit eines Anrufs an Wait aufgerufen wird, wird das Signal ignoriert und verworfen. Es ist nicht in der gleichen Reihenfolge wie ein Semaphor. Tatsächlich hat das Verhalten von Wait und Pulse überhaupt keine inhärente Bedeutung. Die Wait wartet einfach auf eine Änderung im Zustand des erworbenen Schlosses (erworben von Monitor.Enter). Die Pulse ist das Signal, dass sich etwas geändert hat. Deshalb sehen Sie oft Wait genannt in einer while Schleife. Der wartende Thread muss die Wartebedingung erneut testen, da er keine Ahnung hat, was sich geändert hat!

Monitor.Wait und Monitor.Pulse sind grundlegende Synchronisationsmechanismen, die verwendet werden können, um so ziemlich jedes andere Synchronisationsgerät einschließlich Semaphoren zu bilden.

+0

das ist wirklich tolle Antwort! es hat Dinge für mich geklärt! – Andrey

+0

Es ist oft am besten, "Pulse" als ein Signal zu betrachten, dass sich etwas "verändert" haben könnte. Die wesentliche Idee ist, dass eine Methode warten muss, bis sich eine Ressource in irgendeiner Weise ändert (z. B. eine Warteschlange, um Daten darin zu haben), und diese Änderung kann nur durch Code erfolgen, der die Sperre für diese Ressource enthält, die frühere Methode kann testen, ob die Änderung stattgefunden hat und, falls nicht, "Monitor.Wait" auf dem Schloss aufrufen. Wenn jede Methode, die die gesperrten Ressourcen ändert, 'PulseAll' aufruft, wird jeder, der auf eine Änderung wartet, geweckt und hat die Möglichkeit zu sehen, ob die Änderung, auf die sie gewartet haben, passiert ist. – supercat

2

Monitor.Wait/Pulse bietet Ihnen eine Zustandsvariable, die eher einem Auto-Reset-Ereignis als einem Semaphor entspricht (aber nicht genau). Der Hauptunterschied besteht darin, dass ein Semaphor eine Zählung hat, was bedeutet, dass Sie nichts verriegeln müssen, um sicherzustellen, dass Sie keinen Puls verpassen (im Gegensatz zu Monitor.Wait).

Verwandte Themen