Wie verhält sich make (chan bool) anders als make (chan bool, 1)?

9

Meine Frage ergibt sich aus dem Versuch, einen Kanal zu lesen, wenn ich kann, oder schreibe es, wenn ich kann, mit einer select -Anweisung.

Ich weiß, dass Kanäle wie make(chan bool, 1) gepuffert sind, und ein Teil meiner Frage ist, was ist der Unterschied zwischen diesen und make(chan bool) - was diese Seite sagt, ist das gleiche wie make(chan bool, 0) --- was ist der Punkt eines Kanals, der 0 Werte hineinpassen kann?

Siehe Spielplatz A :

%Vor%

Eine Ausgabe:

%Vor%

(Das Entfernen des default case führt zu einem Deadlock !!)

Sehen Sie sich Spielplatz B an:

%Vor%

B Ausgabe:

%Vor%

In meinem Fall ist B Ausgabe was ich will. Was gut sind ungepufferte Kanäle? Alle Beispiele, die ich auf golang.org sehe, benutzen sie, um ein Signal / einen Wert nach dem anderen zu senden (das ist alles was ich brauche) - aber wie in Spielplatz A wird der Kanal niemals gelesen oder geschrieben. Was vermisse ich hier in meinem Verständnis von Kanälen?

    
Matt 18.11.2013, 06:23
quelle

3 Antworten

10
  

Was ist der Punkt eines Kanals, der 0 Werte hineinpassen kann?

Zunächst möchte ich darauf hinweisen, dass der zweite Parameter hier die Puffergröße bedeutet, also einfach ein Kanal ohne Puffer (un-gepufferter Kanal) ist.

Tatsächlich ist das der Grund, warum Ihr Problem erzeugt wird. Nicht gepufferte Kanäle sind nur beschreibbar, wenn jemand blockiert, um von ihr zu lesen, was bedeutet, dass Sie einige Coroutinen haben sollten, um damit zu arbeiten - anstatt dieser einzelnen.

Siehe auch Das Go Memory-Modell :

  

Ein Empfang von einem ungepufferten Kanal findet statt, bevor der Sendevorgang auf diesem Kanal abgeschlossen ist.

    
starrify 18.11.2013, 06:33
quelle
3

Ein ungepufferter Kanal bedeutet, dass Lese- und Schreibvorgänge vom und zum Kanal blockiert werden.

In einer select -Anweisung:

  • Der Lesevorgang würde funktionieren, wenn eine andere Goroutine derzeit auf dem Kanal blockiert wäre
  • Der Schreibvorgang würde funktionieren, wenn eine andere Goroutine beim Lesen des Kanals
  • blockiert war
  • andernfalls wird der Fall default ausgeführt, was in Ihrem Fall A geschieht.
Simon 18.11.2013 06:36
quelle
3

Unbuffered Kanäle (ohne Kapazität erstellt) blockiert den Absender, bis jemand von ihnen lesen kann, damit es wie erwartet funktioniert, sollten Sie zwei goroutines verwenden, um das Deadlock in demselben Thread zu vermeiden.

Zum Beispiel mit diesem Code: Ссылка

Es enthält auch einen Mechanismus für die Hauptfunktion, um zu erkennen, wenn beide Goroutinen beendet sind.

%Vor%

Es wird nicht das alternative Lesen und Schreiben angezeigt, denn sobald send in den Kanal schreibt, wird es blockiert, bevor es das "Schreiben" drucken kann, so dass die Ausführung zu recv geht, das das empfängt Kanal und druckt "Lesen". Es wird versuchen, den Kanal erneut zu lesen, aber es wird blockiert und die Ausführung wird in send verschoben. Nun kann send das erste "Write" schreiben, an den Kanal senden (ohne zu blockieren, da jetzt ein Empfänger bereit ist) und das zweite "Write" schreiben. In jedem Fall ist dies nicht deterministisch und der Scheduler kann die Ausführung zu irgendeinem Zeitpunkt auf irgendeine andere laufende Routine (zumindest in der neuesten 1.2-Version) verschieben.

    
siritinga 18.11.2013 07:00
quelle

Tags und Links