2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
Goroutinen laufen im selben Adressraum, daher muss der Zugriff auf den gemeinsam genutzten Speicher synchronisiert werden.Goroutinen teilen den Speicher durch Kommunikation, anstatt den Speicher zu teilen.
Der Referenztypkanal ist eine spezifische Implementierung des CSP-Modus und wird für die Kommunikation mehrerer Goroutinen verwendet. Es implementiert die Synchronisierung intern, um die Sicherheit der Parallelität zu gewährleisten.
Wie Map ist auch Channel ein Verweis auf die zugrunde liegende Datenstruktur, die von make erstellt wurde.
Wenn wir einen Kanal kopieren oder ihn für die Übergabe von Funktionsparametern verwenden, kopieren wir einfach eine Kanalreferenz, sodass der Aufrufer und der Angerufene auf dasselbe Kanalobjekt verweisen. Wie bei anderen Referenztypen ist der Nullwert des Kanals Null.
Wenn Sie einen Kanal definieren, müssen Sie auch die Art der an den Kanal gesendeten Werte definieren. Kanäle können mit der integrierten Funktion make() erstellt werden:
make (chan Type)
make (chan Type,capacity)
channel<-value //发送value 到channel
<-channel //接收并将其丢弃
x:=<-channel //从 channel 中接收数据,并賦偵给x
x,ok:=<-channel //功能同上,同时检查通道是否已关闭或者是否为空
Standardmäßig blockiert der Kanal das Empfangen und Senden von Daten, es sei denn, das andere Ende ist bereit, wodurch die Goroutine-Synchronisierung einfacher wird, ohne dass explizite Sperren erforderlich sind.
Ein ungepufferter Kanal ist ein Kanal, der vor dem Empfang keinen Wert speichern kann.
Diese Art von Kanal erfordert, dass die sendende Goroutine und die empfangende Goroutine gleichzeitig bereit sind, die Sende- und Empfangsvorgänge abzuschließen. Wenn zwei Goroutinen nicht gleichzeitig bereit sind, bewirkt der Kanal, dass die Goroutine, die zuerst den Sende- oder Empfangsvorgang ausführt, blockiert und wartet.
Dieses Zusammenspiel von Senden und Empfangen an den Kanal ist von Natur aus synchron. Keine Operation kann unabhängig von der anderen existieren.
Die folgende Abbildung zeigt, wie zwei Goroutinen mithilfe ungepufferter Kanäle einen Wert gemeinsam nutzen können:
make (chan Type)//等价于make (chan Type,0)
Wenn keine Puffergröße angegeben ist, ist der Kanal synchron und blockiert daher, bis der Sender sendebereit und der Empfänger empfangsbereit ist.
Ein gepufferter Kanal ist ein Kanal, der vor dem Empfang einen oder mehrere Werte speichern kann.
Für diese Art von Kanal ist es nicht erforderlich, dass die Goroutine gleichzeitig das Senden und Empfangen abschließt. Für Kanäle gelten außerdem unterschiedliche Bedingungen, die Sende- und Empfangsaktionen blockieren. Die Empfangsaktion wird nur blockiert, wenn im zu empfangenden Kanal kein Wert vorhanden ist. Die Sendeaktion wird nur blockiert, wenn der Kanal keinen verfügbaren Puffer für den gesendeten Wert hat.
Dies führt zu einem großen Unterschied zwischen gepufferten und ungepufferten Kanälen: Ungepufferte Kanäle garantieren, dass sendende und empfangende Goroutinen gleichzeitig Daten austauschen; gepufferte Kanäle haben keine solche Garantie.
make (chan Type,capacity)
Wenn eine Pufferkapazität angegeben ist, ist der Kanal asynchron. Solange der Puffer ungenutzten Platz zum Senden von Daten hat oder empfangbare Daten enthält, läuft die Kommunikation ohne Blockierung weiter.
Mit ok kann der Kanal erkennen, ob der Kanal noch geöffnet ist. Wenn der Kanal geschlossen ist, werden die Daten nicht gelesen.
num ,ok:=<-ch
Kann erkennen, ob ein Kanal geschlossen ist.Standardmäßig ist der Kanal ein Dual-Quest-Kanal, d. h. Sie können Daten an ihn senden und Daten von ihm empfangen.
Allerdings sehen wir oft, dass ein Kanal als Parameter übergeben wird und der Wert voraussichtlich nur in eine Richtung verwendet wird, entweder nur zum Senden von Daten oder nur zum Empfangen von Daten. Zu diesem Zeitpunkt können wir die Richtung des Kanals angeben. Die Deklaration einer Einweg-Chamel-Variable ist wie folgt sehr einfach:
var ch1 chan int //ch1双向
var ch2 chan<-float64 //ch2单向,只能用于写float64数据
var ch3 <-chan int //ch3单向,只能用于读int数据
chan<- bedeutet, dass Daten in die Pipe eingegeben werden und die Daten in die Pipe geschrieben und an den Aufrufer ausgegeben werden.
<-chan zeigt an, dass die Daten aus der Pipe kommen. Für den Anrufer werden die Daten aus der Pipe abgerufen, was natürlich die Eingabe ist.
Ein Kanal kann implizit in eine unidirektionale Warteschlange umgewandelt werden, die nur empfängt oder nur sendet, aber ein unidirektionaler Kanal kann nicht in einen normalen Kanal umgewandelt werden;