繁体   English   中英

如何有效地将goroutine中分配的结构通过通道传递回主例程?

[英]How do I efficiently pass a struct allocated in a goroutine back to the main routine via a channel?

在基本级别上,我有一个主例程,该例程生成多个goroutine来处理数据。 每次goroutine处理数据时,它都会发回一个大小可变的结构(每次都包含从goroutine内部分配的切片和/或数组)。

数据不是很大(例如,几兆字节),但是总的来说,将指针转移到数据而不是全部副本是否更有效(并且更安全)? 如果数据结构是静态的,并且我将指针传递给它,则有可能在我仍在处理上一次调用的结果时更改结构(如果它已完全重新分配,那么这可能不是问题)。

发送指向值的指针是可以的并且很常见。 如果该值较大,则发送指向该值的指针将比发送该值更有效。 运行基准以找出“大”的大小。

注意,您必须防止不安全的并发访问该值。 防止不安全的并发访问的常见策略是:

  • 将值的所有权从发送方传递到接收方。 发送者在发送后将不访问该值。 接收者可以用该值做任何想要的事情。
  • 发送后将值视为只读。 发送方或接收方在发送后都不会修改该值。

据我了解,您正在尝试执行以下操作:

func watchHowISoar() (ch chan *bigData) {
    ch = make(chan *bigData)
    go func() {
        for i := 0; i < 10; i++ {
            bd := &bigData{i}
            ch <- bd
            // as long as you don't modify bd inside this goroutine after sending it, you're safe.
        }
        close(ch)
    }()
    return
}
func main() {
    for iamaleafOnTheWind := range watchHowISoar() {
        fmt.Printf("%p\n", iamaleafOnTheWind)
    }
}

只要您在发送后不修改发件人发送的数据,这是绝对安全的。

如果您有疑问,请尝试使用go run -race main.go来运行它,而种族检测器并不完美,它通常会检测出类似的东西。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM