没有看到goroutines预期的副作用

时间:2015-04-16 17:52:39

标签: concurrency go append slice goroutine

我试图抓住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()),它会打印两个空切片。为什么这不起作用?

1 个答案:

答案 0 :(得分:6)

在您使用sync.WaitGroup,频道或其他机制明确等待它们之前,您启动的任何goroutine都不能完成(甚至开始!)。 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()
}

(只是谈到风格,如果是我I'd make this function return the enlarged slice so it's similar to append() itself)和Go代码审核评论suggest passing values,尽管是it's not at all unconventional to extend a slice passed as a pointer receiver ("this") parameter。)