Go 语言简介(下)— 特性
希望你看到这篇文章的时候还是在公交车和地铁上正在上下班的时间,我希望我的这篇文章可以让你利用这段时间了解一门语言。当然,希望你不会因为看我的文章而错过站。呵呵。
如果你还不了解Go语言的语法,还请你移步先看一下上篇——《Go语言简介(上):语法》
目录
goroutine
GoRoutine主要是使用go关键字来调用函数,你还可以使用匿名函数,如下所示:
package main import "fmt" func f(msg string) { fmt.Println(msg) } func main(){ go f("goroutine") go func(msg string) { fmt.Println(msg) }("going") }
我们再来看一个示例,下面的代码中包括很多内容,包括时间处理,随机数处理,还有goroutine的代码。如果你熟悉C语言,你应该会很容易理解下面的代码。
你可以简单的把go关键字调用的函数想像成pthread_create。下面的代码使用for循环创建了3个线程,每个线程使用一个随机的Sleep时间,然后在routine()函数中会输出一些线程执行的时间信息。
package main import "fmt" import "time" import "math/rand" func routine(name string, delay time.Duration) { t0 := time.Now() fmt.Println(name, " start at ", t0) time.Sleep(delay) t1 := time.Now() fmt.Println(name, " end at ", t1) fmt.Println(name, " lasted ", t1.Sub(t0)) } func main() { //生成随机种子 rand.Seed(time.Now().Unix()) var name string for i:=0; i<3; i++{ name = fmt.Sprintf("go_%02d", i) //生成ID //生成随机等待时间,从0-4秒 go routine(name, time.Duration(rand.Intn(5)) * time.Second) } //让主进程停住,不然主进程退了,goroutine也就退了 var input string fmt.Scanln(&input) fmt.Println("done") }
运行的结果可能是:
go_00 start at 2012-11-04 19:46:35.8974894 +0800 +0800 go_01 start at 2012-11-04 19:46:35.8974894 +0800 +0800 go_02 start at 2012-11-04 19:46:35.8974894 +0800 +0800 go_01 end at 2012-11-04 19:46:36.8975894 +0800 +0800 go_01 lasted 1.0001s go_02 end at 2012-11-04 19:46:38.8987895 +0800 +0800 go_02 lasted 3.0013001s go_00 end at 2012-11-04 19:46:39.8978894 +0800 +0800 go_00 lasted 4.0004s
goroutine的并发安全性
关于goroutine,我试了一下,无论是Windows还是Linux,基本上来说是用操作系统的线程来实现的。不过,goroutine有个特性,也就是说,如果一个goroutine没有被阻塞,那么别的goroutine就不会得到执行。这并不