没有看到goroutine产生预期的副作用。

huangapple go评论76阅读模式
英文:

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 &quot;fmt&quot;

var (
    b1 []float64
    b2 []float64
)

func main() {
    go fill(&amp;b1, 10)
    go fill(&amp;b2, 10)
    
    fmt.Println(b1,b2)

    var s string
    fmt.Scanln(&amp;s)
}

func fill(a *[]float64, n int) {
    for i:=0; i&lt;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 (
	&quot;fmt&quot;
	&quot;math/rand&quot;
	&quot;sync&quot;
)

var (
	b1 []float64
	b2 []float64
)

func main() {
	wg := new(sync.WaitGroup)
	wg.Add(2)
	go fill(&amp;b1, 10, wg)
	go fill(&amp;b2, 10, wg)
	wg.Wait()

	fmt.Println(b1)
	fmt.Println(b2)
}

func fill(a *[]float64, n int, wg *sync.WaitGroup) {
	for i := 0; i &lt; 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.)

huangapple
  • 本文由 发表于 2015年4月17日 01:52:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/29682422.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定