[英]How do I efficiently pass a struct allocated in a goroutine back to the main routine via a channel?
At a basic level, I have a main routine that spawns multiple goroutines to process data. 在基本级别上,我有一个主例程,该例程生成多个goroutine来处理数据。 Every time a goroutine processes the data it sends back a struct of varying size (it contains slices and/or arrays allocated from within the goroutine each time).
每次goroutine处理数据时,它都会发回一个大小可变的结构(每次都包含从goroutine内部分配的切片和/或数组)。
The data isn't huge (say, a few megabytes) but in general is it more efficient (and is it safe) to transfer a pointer to the data versus a copy of it all? 数据不是很大(例如,几兆字节),但是总的来说,将指针转移到数据而不是全部副本是否更有效(并且更安全)? If the data structure is static and I transfer a pointer to it, there's a risk that the structure may change while I'm still processing the result of the previous invocation (if it's fully reallocated then perhaps that's not an issue).
如果数据结构是静态的,并且我将指针传递给它,则有可能在我仍在处理上一次调用的结果时更改结构(如果它已完全重新分配,那么这可能不是问题)。
It's OK and common to send pointers to values. 发送指向值的指针是可以的并且很常见。 If the value is large, sending a pointer to the value will be more efficient than sending the value.
如果该值较大,则发送指向该值的指针将比发送该值更有效。 Run a benchmark to find out how large is "large".
运行基准以找出“大”的大小。
The caveat is that you must prevent unsafe concurrent access to the value. 注意,您必须防止不安全的并发访问该值。 Common strategies for preventing unsafe concurrent access are:
防止不安全的并发访问的常见策略是:
From my understanding you're trying to do something like: 据我了解,您正在尝试执行以下操作:
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)
}
}
And it is perfectly safe as long as you don't modify the sent data from the sender after you send it. 只要您在发送后不修改发件人发送的数据,这是绝对安全的。
If you have doubts, try to run it with go run -race main.go
, while the race detector isn't perfect, it will usually detect things like that. 如果您有疑问,请尝试使用
go run -race main.go
来运行它,而种族检测器并不完美,它通常会检测出类似的东西。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.