为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
慕勒3428872 2021-08-16 20:07:47
在基本层面上,我有一个主程序,它产生多个 goroutine 来处理数据。每次 goroutine 处理数据时,它都会发回一个不同大小的结构(它包含每次从 goroutine 内部分配的切片和/或数组)。数据不是很大(比如几兆字节),但总的来说,传输指向数据的指针与传输数据的副本相比是否更有效(并且安全)?如果数据结构是静态的并且我传输了一个指向它的指针,那么在我仍在处理上一次调用的结果时,结构可能会发生变化(如果它完全重新分配,那么这可能不是问题)。
查看完整描述

2 回答

?
qq_笑_17

TA贡献1818条经验 获得超7个赞

发送指向值的指针是正常且常见的。如果值很大,发送一个指向该值的指针会比发送该值更高效。运行基准测试以找出“大”有多大。

需要注意的是,您必须防止对值进行不安全的并发访问。防止不安全并发访问的常见策略有:

  • 将值的所有权从发送方传递给接收方。发送者发送后不访问该值。接收者可以对这个值做任何它想做的事情。

  • 发送后将该值视为只读。发送者或接收者都不会在发送后修改该值。


查看完整回答
反对 回复 2021-08-16
?
翻阅古今

TA贡献1780条经验 获得超5个赞

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


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,虽然竞态检测器并不完美,但它通常会检测到类似的东西。


查看完整回答
反对 回复 2021-08-16
  • 2 回答
  • 0 关注
  • 216 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信