英文:
Not seeing the expected side effects from goroutines
问题
我正在尝试理解goroutines。看看这段代码:
package main
import "fmt"
var (
b1 []float64
b2 []float64
)
func main() {
go fill(&b1, 10)
go fill(&b2, 10)
fmt.Println(b1,b2)
var s string
fmt.Scanln(&s)
}
func fill(a *[]float64, n int) {
for i:=0; i<n; i++ {
*a = append(*a, rand.Float64()*100)
}
}
你可以看到,我试图填充两个切片。但是当以这种方式运行(使用go fill()
)时,它打印出两个空切片。为什么会这样?
英文:
I'm trying to get a grasp on goroutines. Take this code:
package main
import "fmt"
var (
b1 []float64
b2 []float64
)
func main() {
go fill(&b1, 10)
go fill(&b2, 10)
fmt.Println(b1,b2)
var s string
fmt.Scanln(&s)
}
func fill(a *[]float64, n int) {
for i:=0; i<n; i++ {
*a = append(*a, rand.Float64()*100)
}
}
As you see, I'm trying to fill two slices. But when run this way (with go fill()
), it prints two empty slices. Why is this not working?
答案1
得分: 6
你好,以下是翻译好的内容:
任何你启动的 goroutine 都不能保证已经完成(甚至开始!)直到你显式地等待它们使用 sync.WaitGroup
、通道或其他机制。这个例子可以工作:
package main
import (
"fmt"
"math/rand"
"sync"
)
var (
b1 []float64
b2 []float64
)
func main() {
wg := new(sync.WaitGroup)
wg.Add(2)
go fill(&b1, 10, wg)
go fill(&b2, 10, wg)
wg.Wait()
fmt.Println(b1)
fmt.Println(b2)
}
func fill(a *[]float64, n int, wg *sync.WaitGroup) {
for i := 0; i < n; i++ {
*a = append(*a, rand.Float64()*100)
}
wg.Done()
}
(就风格而言,如果是我,我会使这个函数返回扩展后的切片,这样它就类似于 append()
本身,而 Go 的代码审查评论 建议传递值,尽管将作为指针 接收者("this")参数传递的切片扩展并不常见。)
英文:
Any goroutines you start aren't guaranteed to have finished (or even started!) until you've explicitly waited on them using a sync.WaitGroup
, channel, or other mechanism. This works:
package main
import (
"fmt"
"math/rand"
"sync"
)
var (
b1 []float64
b2 []float64
)
func main() {
wg := new(sync.WaitGroup)
wg.Add(2)
go fill(&b1, 10, wg)
go fill(&b2, 10, wg)
wg.Wait()
fmt.Println(b1)
fmt.Println(b2)
}
func fill(a *[]float64, n int, wg *sync.WaitGroup) {
for i := 0; i < n; i++ {
*a = append(*a, rand.Float64()*100)
}
wg.Done()
}
(Just speaking of style, if it were me I'd make this function return the enlarged slice so it's similar to append()
itself, and Go's Code Review Comments suggest passing values, though it's not at all unconventional to extend a slice passed as a pointer receiver ("this") parameter.)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论