Не увидеть ожидаемых побочных эффектов от горутин

Я пытаюсь понять горутины. Возьмите этот код:

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()) он печатает два пустых фрагмента. Почему это не работает?


person hmnhmn    schedule 16.04.2015    source источник
comment
Любая горутина, которую вы запускаете, не обязательно завершится, пока вы не дождетесь ее с помощью sync.WaitGroup, канала или какого-либо другого механизма.   -  person twotwotwo    schedule 16.04.2015


Ответы (1)


Любые горутины, которые вы запускаете, не обязательно будут завершены (или даже запущены!), пока вы явно не подождите их, используя 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()
}

(Просто говоря о стиле, если бы я I' d сделать так, чтобы эта функция возвращала увеличенный срез, чтобы он был похож на сам append(), и комментарии к обзору кода Go предлагать передаваемые значения, хотя не совсем необычно расширять фрагмент, переданный как параметр указателя receiver ("this").)

person twotwotwo    schedule 16.04.2015