初学Go语言,对channel、并发的疑问


初学go语言,对channel、并发感觉不太好理解。希望高人指点下。
下面的代码是我看到一本书上的,就是讲解channel的。


 package main

import (
    "fmt"
    "math/rand"
)

func test(ch chan int, i int) {
    ch <- rand.Int()
    fmt.Println(i, "go...")
}

func main() {
    chs := make([]chan int, 10)
    for i := 0; i < 10; i++ {
        chs[i] = make(chan int)
        go test(chs[i], i)
    }
    for _, ch := range chs {
        value := <-ch
        fmt.Println(value)
    }
    var i int
    fmt.Scan(&i)
    fmt.Println("done")
}

这个程序的输出是


 0 go...
134020434
1597969999
1721070109
2068675587
1237770961
220031192
2031484958
583324308
958990240
413002649
1 go...
2 go...
3 go...
4 go...
5 go...
6 go...
7 go...
8 go...
9 go...

我的疑惑是,为什么第一个打印出来的是0 go...?
我想来想去还觉得应该是先输出随机数,然后才输出0 go..., 1 go..., 2 go..., .........呀。
如果先打印了0 go...,那么后面的1 go...,2 go...不是也应该和随机数间隔打印出来吗?

channel 并发 go

一代阿迪王 10 years, 1 month ago

因为这是有缓存通道

万里谷佑理 answered 10 years, 1 month ago

写并发要注意的一点就是,不要考虑先后的问题,因为这和系统底层调度有关。上层代码要关注的问题是同步和死锁。

根据输出结果,我们也可以大概猜测一下它的运行机制:

main 里有两个循环,当第一个循环运行结束后,第一个生成的test 也运行完毕了,所以会输出 "0 go"。 "<-" 操作在返回时相对耗时一些,所以会导致之后的结果 "* go" 会堆在后面。

洋洋o嗯嗯 answered 10 years, 1 month ago

没看明白啥意思, 默认go是单线程运行的, 你设下gomaxprocs试试看

一顾倾人城 answered 10 years, 1 month ago

Your Answer