转载

深入Go语言 - 8

本章介绍 go语句、goroutine调度。

go 语句

go语句用来产生一个新的goroutine,并执行一个函数,它的使用非常简单,就是在函数调用或者方法调用的前面加上go关键字即可。

深入go语句

看下面一段代码,你觉得会输出什么:

packagemain  import"fmt"  funcmain() {  fori :=0; i <3; i++ { gofunc() {  fmt.Println(i)  }()  } } 

有的人说输出"1 2 3",有的人说输出"3 3 3"。

但实际上什么都没有输出。这是因为main goroutine马上就执行完了,它不会等待生成的goroutine的执行。

Program execution begins by initializing the main package and then invoking the function main. When that function invocation returns, the program exits. It does not wait for other (non-main) goroutines to complete.

你可以增加下面一行,等待所有的 goroutine 执行完:

select{} 

因为select语句会被阻塞,所以前面生成的所有的goroutine会被执行。

你可能会发现程序最后会出下面一个错误信息:

fatalerror: all goroutines are asleep - deadlock! 

它的意思是所有的goroutine都已经执行完了,你的select还在那里阻塞着,不会有case等你执行的,所以有死锁的可能。Go强制杀死了这个等待,并抛出了一个错误。因此你可以忽略这个错误,它对我们前面的程序执行没有影响。

如果你不想看到这个错误,你可以使用 sync.WaitGroup 或者像其它程序一样从命令行读取命令造成main goroutine阻塞,或者time.Sleep较长的一个时间:

os.Stdin.Read(make([]byte,1)) 

那么,加上上面一行,会输出什么?

答案是 "3 3 3"。

goroutine是什么

goroutine的调度

原文  http://colobu.com/2016/06/27/dive-into-go-8/
正文到此结束
Loading...