Heim > Backend-Entwicklung > Golang > Über Kanäle und Goroutinen in Slices schreiben: Warum Slices leer bleiben

Über Kanäle und Goroutinen in Slices schreiben: Warum Slices leer bleiben

王林
Freigeben: 2024-02-11 18:50:08
nach vorne
1274 Leute haben es durchsucht

通过通道和 goroutine 写入切片:为什么切片最终为空

php-Editor Yuzai stellt Ihnen eine Frage zum Slicing: Warum ist das Schreiben in den Slice über Kanäle und Goroutine am Ende leer? In Go sind Kanäle und Goroutinen wichtige Werkzeuge für die gleichzeitige Programmierung, aber in manchen Fällen kann ihre Verwendung zum Schreiben von Slices zu unerwarteten Ergebnissen führen. In diesem Artikel wird die Ursache dieses Problems ausführlich erläutert und Lösungen bereitgestellt, die Ihnen helfen, diese Situation besser zu verstehen und damit umzugehen.

Frageninhalt

Ich führe diese Funktion aus:

func run() () {
    // this slice is going to be filled out by a channel and goroutine.
    vertices := make([]vertex, 0)

    var wg sync.waitgroup

    // obtain a writer to fill out the vertices.
    writer := writer(&wg, vertices)

    // run an arbitrary logic to send data to writer.
    logic(writer)

    // stop the writer reading on the channel.
    close(writer)

    // wait for the write to complete.
    wg.wait()

    // see if vertices slice is actually filled out.
    doublecheckvertices(vertices)
}
Nach dem Login kopieren

Aber am Ende ist mein vertices Stück leer:

func doublecheckvertices(vertices []vertex) () {
    // here i notice that `vertices` slice is actually empty :(

}
Nach dem Login kopieren

Die Funktion, die writer zurückgibt, sieht folgendermaßen aus:

func writer(wg *sync.waitgroup, vertices []vertex) (chan<- []*triangle3) {
    // external code writes to this channel.
    // this goroutine reads the channel and writes to vertices.
    writer := make(chan []*triangle3)

    // write by a goroutine.
    wg.add(1)
    go func() {
        defer wg.done()

        a := vertex{}

        // read from the channel and write them to vertices.
        for ts := range writer {
            for _, t := range ts {
                a.x = float32(t.v[0].x)
                a.y = float32(t.v[0].y)
                a.z = float32(t.v[0].z)
                vertices = append(vertices, a)
            }
        }
    }()

    return writer
}
Nach dem Login kopieren

Kann mir jemand helfen herauszufinden, warum mein vertices-Slice leer bleibt?

Protokoll

Das Protokoll zeigt, dass vertices 切片实际上已填充。但由于某种原因,传递给doublecheckvertices der Slice tatsächlich gefüllt ist. Aber aus irgendeinem Grund ist es leer, wenn es an doublecheckvertices übergeben wird.

                vertices = append(vertices, a)
                // This Log shows the slice is actually filled out:
                fmt.Printf("vertices len() is %v\n", len(vertices))
Nach dem Login kopieren

Workaround

Das sieht ähnlich aus wie „den Slice als Funktionsargument übergeben und den ursprünglichen Slice ändern

Wenn Sie möchten, dass die Goroutine ein extern erstelltes Slice ändert, benötigen Sie einen Zeiger auf das Slice:

func Writer(wg *sync.WaitGroup, vertices *[]Vertex) (chan<- []*Triangle3) {
    // External code writes to this channel.
    // This goroutine reads the channel and writes to vertices.
    writer := make(chan []*Triangle3)

    // Write by a goroutine.
    wg.Add(1)
    go func() {
        defer wg.Done()

        a := Vertex{}

        // Read from the channel and write them to vertices.
        for ts := range writer {
            for _, t := range ts {
                a.X = float32(t.V[0].X)
                a.Y = float32(t.V[0].Y)
                a.Z = float32(t.V[0].Z)
                *vertices = append(*vertices, a)  <=====
            }
        }
    }()

    return writer
}
Nach dem Login kopieren

Das obige ist der detaillierte Inhalt vonÜber Kanäle und Goroutinen in Slices schreiben: Warum Slices leer bleiben. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:stackoverflow.com
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage