簡體   English   中英

如果通過Golang通道發送,是否在goroutines之間實際復制了一個struct?

[英]Is a struct actually copied between goroutines if sent over a Golang channel?

如果通過Go中的通道發送大型結構,它是否真的在goroutines之間復制?

例如,在下面的代碼中,Go實際上會復制goroutines生產者和消費者之間的所有largeStruct數據嗎?

package main

import (
    "fmt"
    "sync"
)

type largeStruct struct {
    buf [10000]int
}

func main() {
    ch := make(chan largeStruct)
    wg := &sync.WaitGroup{}
    wg.Add(2)
    go consumer(wg, ch)
    go producer(wg, ch)
    wg.Wait()
}

func producer(wg *sync.WaitGroup, output chan<- largeStruct) {
    defer wg.Done()
    for i := 0; i < 5; i++ {
        fmt.Printf("producer: %d\n", i)
        output <- largeStruct{}
    }
    close(output)
}

func consumer(wg *sync.WaitGroup, input <-chan largeStruct) {
    defer wg.Done()
    i := 0
LOOP:
    for {
        select {
        case _, ok := <-input:
            if !ok {
                break LOOP
            }
            fmt.Printf("consumer: %d\n", i)
            i++
        }
    }
}

游樂場: http//play.golang.org/p/fawEQnSDwB

是的,一切都是Go中的副本,您可以通過更改頻道使用指針(aka chan *largeStruct )輕松解決這個問題。

// demo: http//play.golang.org/p/CANxwt8s2B

正如您所看到的,指向v.buf的指針在每種情況下都是不同的,但是如果將其更改為chan *largeStruct ,則指針將是相同的。

@LucasJones提供了一個更容易理解的例子: https//play.golang.org/p/-VFWCgOnh0

正如@nos所指出的那樣,如果你在發送它之后修改兩個goroutine中的值,就會有一個潛在的競爭。

Go編程語言規范

發送聲明

send語句在通道上發送值。 通道表達式必須是通道類型,通道方向必須允許發送操作,並且要發送的值的類型必須可分配給通道的元素類型。

它是一個副本,因為通過賦值到通道的元素類型將值發送到通道。 如果值是結構,則復制結構。 如果值是指向結構的指針,則復制指向結構的指針。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM