Frage

Beim Lesen C # 3.0 in a Nutshell von Joseph und Ben Albahari , stieß ich auf dem folgenden Absatz (Seite 673, erster Absatz in Abschnitt mit dem Titel " Melden mit Warten und Pulse ")

  

"Die Monitor Klasse stellt ein weiteres Signalisierungs Konstrukt über zwei statische Methoden, Warten und Pulse . Das Prinzip besteht darin, dass Sie die Signalisierungslogik schreiben selbst benutzerdefinierte Fahnen mit und Feldern (eingeschlossen in Sperre Anweisungen), und dann einführen Warten und Pulse Befehle zur Milderung CPU Spinnen. der Vorteil dieses Low-Level-Ansatz ist, dass mit nur Warten , Pulse und Sperre Anweisung, können Sie die Funktionalität von erreichen Autoreset , Manual und Semaphore sowie Waithandle 's statische Methoden WaitAll und WaitAny . Des Weiteren Warten und Pulse   kann in Situationen geeignet sein, wo   alle die Warte Griffe   geizig in Frage gestellt. "

Meine Frage ist, was ist die richtige Interpretation des letzten Satzes?

  • Eine Situation mit einer anständigen / großen Anzahl von Warte Griff wo WaitOne () nur gelegentlich auf einem bestimmten Wartegriff genannt.
  • Eine Situation mit einem anständigen / große Anzahl von Warte Griffe, wo selten nicht mehr als ein Thread dazu neigen, an einem bestimmten Warte Griff zu sperren.
  • Einige andere Interpretation.

würde es begrüßen, auch Beispiele für solche Situationen beleuchten und vielleicht, wie und / oder warum sie effizienter über Wait behandelt und Pulse und nicht durch andere Methoden.

Danke!

Edit: Ich fand den Text Online hier

War es hilfreich?

Lösung

Was dies sagt, ist, dass es einige Situationen, in denen Warten und Pulse eine einfachere Lösung als Warte Griffe zur Verfügung stellen. In der Regel geschieht dies gilt:

  • Der Kellner, und nicht der Antragsteller, entscheidet, wann zu entsperren
  • Der Sperrzustand ist mehr als ein einfaches Flag (vielleicht mehr Variablen)

Sie können nach wie vor Warte Griff in diesen Situationen verwenden, aber Warten / Pulse einfacher zu sein tendiert. Die große Sache über Wait / Impuls ist, dass die zugrunde liegenden Warten Sperre aufgehoben während des Wartens. Zum Beispiel in dem folgenden Beispiel, wir lesen _x und _y in der Sicherheit eines Schlosses - und doch, dass Sperre aufgehoben wird während des Wartens, so dass ein anderer Thread diese Variablen aktualisieren:

lock (_locker)
{
  while (_x < 10 && _y < 20) Monitor.Wait (_locker);
}

Ein anderer Thread kann dann aktualisieren _x und _y atomar (aufgrund der Sperre) und dann Pulse die Kellner zu signalisieren:

lock (_locker)
{
  _x = 20;
  _y = 30;
  Monitor.Pulse (_locker);
} 

Der Nachteil Wait / Pulse ist, dass es einfacher ist es falsch zu bekommen und einen Fehler machen (zum Beispiel durch eine variable Aktualisierung und Pulse zu vergessen). In Situationen, in denen ein Programm mit Wartegriffen auf ein Programm mit Wait / Pulse ebenso einfach ist, würde ich empfehlen, mit Warte Griffen aus diesem Grunde gehen.

Im Hinblick auf die Effizienz / Ressourcenverbrauch (was ich denke, das Sie spielt damit auf), Warten / Impuls ist in der Regel schneller und leichter (da es eine verwaltete Implementierung hat). Dies ist selten eine große Sache in der Praxis aber. Und an diesem Punkt, Framework 4.0 enthält mit geringen Overhead verwaltet Versionen von Manual und Semaphore (ManualResetEventSlim und SemaphoreSlim).

Framework 4.0 auch viele weitere Synchronisationsoptionen dass lessen die Notwendigkeit Wait / Impuls sieht vor:

  • CountdownEvent
  • Barrier
  • PLINQ / Daten Parallelism (AsParallel, Parallel.Invoke, Parallel.For, Parallel.ForEach)
  • Aufgaben und Fortsetzungen

Alle diese sind viel höhere Ebene als Wait / Impuls und sind IMO bevorzugt für das Schreiben von zuverlässigem und wartbaren Code (vorausgesetzt, sie werden die Aufgabe lösen).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top