Der Grund, warum wir direkt beenden, liegt darin, dass der Haupt- und der FMT-Druck in unserem Code gleichzeitig ausgeführt werden. Wenn FMT Daten dringend druckt, bevor sie eintreffen, ist die äußere Schleife bereits beendet und wird dann direkt beendet.
. 🎜🎜🎜🎜🎜🎜2
Wie Sie im obigen Fall sehen können, können Sie die Make-Funktion direkt verwenden, um einen Kanal zu erstellen.
Sie können sehen, dass zu diesem Zeitpunkt ein Fehler gemeldet wurde. Der Fehler bedeutet, dass beim Senden von 1 an den Kanal ein Deadlock auftritt.
Dann gehe zurück zum vorherigen Bild.
Wie wir oben gesagt haben, ist Kanal eine Interaktion zwischen Goroutine und Goroutine.
Aber in diesem Fall gibt es nur eine Goroutine, daher ist eine andere Goroutine erforderlich, um sie zu empfangen.
Jetzt solltest du wissen, wie man eine Goroutine startet.
Im Bild oben haben wir eine weitere Goroutine neu geöffnet und dann eine Endlosschleife verwendet, um den vom Kanal gesendeten Wert zu empfangen und auszudrucken.
Aber Sie werden feststellen, dass wir zwei Daten an den Kanal gesendet haben, das Druckergebnis zu diesem Zeitpunkt jedoch nur ein Datenelement enthält. Aber es ist besser als das, womit wir angefangen haben, richtig!
Sie können den Ausführungsprozess des Codes verstehen. Zuerst wird eine 1 an den Kanal gesendet und dann der erste Wert in einer Schleife abgerufen und gedruckt.
Daten 2 erneut an den Kanal senden, aber direkt vor dem Drucken beenden, was zu dem Phänomen führt, dass nur Daten 1 angezeigt werden, nicht jedoch Daten 2.
Durch Kakas Beschreibung sollten Sie bereits wissen, wie Sie dieses Problem lösen können.
Das heißt, der Funktion „channelDome“ eine verzögerte Ausgangszeit hinzuzufügen.
Kanal als Parameter übergeben
Wie Sie oben sehen können, folgt auf go eine Abschlussfunktion, und das in diesem Abschluss verwendete c ist die äußere Schicht, die c verwendet wird.
Ist es also möglich, dieses c mithilfe von Parametern zu übergeben? Die Antwort ist ja.
Natürlich können Sie auch andere Parameter übergeben
Sie können dem obigen Bild entnehmen, dass nicht nur der Kanal, sondern auch der ID-Parameter übergeben wird. Gleichzeitig kann der Code auch direkt in den eingeschlossenen Teil, also den Wert, optimiert werden direkt vom Kanal übernommen.
Erstellen Sie mehrere Kanäle
Wie Sie auf dem Bild oben sehen können, hat jeder seinen eigenen Kanal und verteilt ihn dann. Nach der Verteilung erhält jeder seinen eigenen erhaltenen Wert und Druck es raus.
Ähnlich können Sie sehen, dass wir in Zeile 26 eine neue for-Schleife hinzugefügt haben, um Daten an den Kanal zu senden.
Aus den laufenden Ergebnissen werden Sie feststellen, dass die Druckreihenfolge verwirrend ist, z. B. die beiden Werte „receive i“ und „receive I“.
Haben Sie an dieser Stelle irgendwelche Zweifel? Wenn wir Daten an den Kanal senden, senden wir sie der Reihe nach! Dann müssen sie beim Empfang in der richtigen Reihenfolge empfangen werden.
Da wir sehr sicher sind, dass die Daten in der richtigen Reihenfolge gesendet werden, kann das Problem nur bei Printf auftreten.
Da Printf über E/A verfügt und von Goroutine geplant wird, ist Printf zu diesem Zeitpunkt außer Betrieb, aber die empfangenen Werte werden einzeln ausgedruckt.
Kanal als Rückgabewert verwenden
Die Fälle in den vorherigen Abschnitten wurden alle von Kanal erstellt und dann als Parameter übergeben.
Dann gibt dieser Abschnitt den Kanal als Rückgabewert zurück.
package mainimport (
"fmt"
"time")func createWorker(id int) chan int {
c := make(chan int)
go func() {
for {
fmt.Printf("Worker %d receive %c\n", id,
Nach dem Login kopieren
Von hier aus können Sie sehen, dass wir die Worker-Funktion in die createWorker-Funktion geändert haben, da in dieser Funktion der Kanal direkt erstellt wird.
Dann wird der vom Kanal empfangene Wert über eine Coroutine gedruckt.
Werfen wir einen Blick auf die Laufergebnisse
Aus den laufenden Ergebnissen können Sie erkennen, dass unser Codeschreiben immer noch korrekt ist, aber Sie können sehen, wie Sie den zu diesem Zeitpunkt zurückgegebenen Kanal sehr intuitiv verwenden können.
Aber wenn es viele Codes gibt, wissen Sie es nicht Wie man diesen Kanal überhaupt nutzt, dieser gesamte Code muss einfach geändert werden.
Dann muss man den Leuten draußen sagen, wie man es benutzt.
Aus dem obigen Code können Sie erkennen, dass Daten an den Kanal gesendet werden. Daher sollte der von der createWorker
-Methode zurückgegebene Kanal mit
markiert sein
Der aktuelle Code sieht also so aus. Wir markieren direkt die Richtung des Rückgabewertkanals der createWorker-Methode. Die Funktion besteht darin, Daten zu senden.
Beim Drucken ist es dann der Beleg, der sehr intuitiv aussieht.
Nachdem Sie die beiden oben genannten Schritte geändert haben, werden Sie feststellen: createWorker
调用是报错了,Cannot use 'createWorker(i)' (type chanWenn Sie den Fehler sehen, sollten Sie wissen, dass die beiden Typen nicht gleichwertig sind.
Nach der Änderung werden Sie feststellen, dass die Kompilierung korrekt ist und keine Fehlermeldung gemeldet wird.
Lassen Sie uns über die gleichzeitige Programmierung in Go (1) sprechen.也是ok的。
package mainimport (
"fmt"
"time")func createWorker(id int) chan
Nach dem Login kopieren
学习了这么久了,那么咔咔问你一个问题,这段代码执行会发生什么?
Ja, es wird ein Fehler auftreten, denn wie am Anfang des Artikels erwähnt, müssen Sie zum Senden von Daten an einen Kanal eine andere Coroutine öffnen, um die Daten zu empfangen.
Obwohl Coroutinen als leichtgewichtig gelten, müssen Sie nach dem Senden von Daten die Coroutinen wechseln, um Daten zu empfangen, was sehr ressourcenintensiv ist.
Dann erkläre ich dir das in diesem Abschnitt.
Erstellen Sie einen Kanal, der 3 Puffer haben kann, und senden Sie dann 3 Daten an den Kanal.
An den Ergebnissen des gleichzeitigen Laufens können Sie auch erkennen, dass es nicht passiertdeadlock
.
Eine Frage an Sie: Was passiert, wenn Sie Daten 4 an den Puffer senden?
Du bist schlau, du musst über das Ergebnis nachgedacht haben, ja, es gemeldetdeadlock
Dann verwenden wir den vorherigen Arbeiter, um die Kanaldaten zu empfangen.
Aber Sie werden feststellen, dass das laufende Ergebnis die eingesandten 1,2,3,4 immer noch nicht ausdruckt.
Diese Frage wurde jetzt schon mehrmals gestellt. Sie können versuchen, sich zu fragen, wie Sie diese Situation lösen sollten.
Fügen Sie einfach eine Verzögerungszeit hinzu. Lassen Sie mich Ihnen übrigens erklären, dass im vorherigen Fall Buchstaben und alle Formatierungen %c gedruckt wurden, jetzt werden Zahlen gedruckt, also ändern Sie Für %d, eine kleine Änderung .
Die Einrichtung von Kanälen auf diese Weise hat einen gewissen Effekt auf die Leistungssteigerung.
Haben Sie bisher ein Problem festgestellt, das heißt, Sie wissen nicht, wann der Kanal versendet wurde?
Schauen wir uns als nächstes dieses Problem an.
Leihen Sie sich den Code aus dem vorherigen Fall aus, um mit der Erklärung fortzufahren.
Was mit dem vorherigen Code nicht übereinstimmt, ist, dass wir am Ende „close“ hinzugefügt haben. Es ist zu beachten, dass „close“ für den Absender geschlossen ist.
Sie werden sehen, dass die Laufergebnisse nicht zufriedenstellend sind. Sie werden feststellen, dass 1,2,3,4 eingegangen sind.
Aber unten wurden viele Nullen empfangen, aber der Screenshot erfasste nur ein Datenelement.
Obwohl der Absender den Kanal schließt, empfängt der Arbeiter weiterhin die Daten, wenn der Kanal geschlossen wird. Dies bedeutet nicht, dass die Daten nach dem Schließen des Kanals nicht empfangen werden.
Aber wenn der Absender den Kanal auf „Schließen“ setzt, sind die empfangenen Daten alle 0, dh der Wert des von der Worker-Methode übergebenen Parameters c chan int ist 0.
Jetzt ist unser Kanal vom Typ int und wir haben 0 erhalten. Wenn es sich dann um einen String-Typ handelt, wird ein leerer String empfangen.
Wie lange wird das dauern? Das ist die von uns festgelegte Zeit von einer Millisekunde.
Wenn Sie gebeten wurden, dieses Programm zu ändern, haben Sie irgendwelche Ideen? Wenn Sie keine Ahnung haben, wiegen Sie einfach mit diesem Rhythmus.
Im Funktionsarbeiter werden zwei Werte zum Empfangen verwendet, n ist der übergebene Kanal c. ok dient dazu, festzustellen, ob der Wert vorhanden ist.
Sie können die laufenden Ergebnisse sehen und erhalten keine 0 Daten mehr.
Zusätzlich zu dieser Schreibweise gibt es noch eine einfachere Möglichkeit.
Beharrlichkeit beim Lernen, Beharrlichkeit beim Schreiben und Beharrlichkeit beim Teilen sind die Überzeugungen, an denen Kaka seit seinen Anfängen festgehalten hat. Ich hoffe, dass Kakas Artikel im riesigen Internet Ihnen ein wenig helfen können. Ich bin Kaka, bis zum nächsten Mal.