2015-04-16 53 views
1

我試圖抓住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()),它會打印兩個空片。爲什麼這不起作用?

+3

你開始不能保證完成,直到你等待它的任何夠程與'sync.WaitGroup',頻道或其他機制。 – twotwotwo

回答

6

在開始使用sync.WaitGroup,頻道或其他機制明確等待它們之前,您開始的任何套餐都不能保證完成(甚至無法啓動!)。 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