Go的并发

来源:互联网 发布:2016网络大电影 编辑:程序博客网 时间:2024/06/13 00:43

首先并行!=并发,并发是逻辑上的并行.
例如:多个程序在单核处理器上运行,每个程序只能在对应的时间片上运行,因为时间片很短,看起来就像是并行.
一.go语言级别的线程goroutine
goroutine是Go语言中的轻量级线程实现.它是一个普通的函数,只需使用保留字 go 作为开头。
例如:两个goroutine打印1-10

//这个程序是不会输出的,因为go还没执行完成,main已经退出了func test(){    for i:=0; i<10 ;i++{        fmt.Print(i)    }}func main()  {    go test()    go test()}

解决上面的问题可以让main等待一段时间,让test执行完成,也可以使用信道进行通信.
1)在main的最后加上time.Sleep(time.Second) 停顿一秒
2)使用信道:channel

func test(){    for i:=0; i<10 ;i++{        fmt.Print(i)    }    ch<-0}func main()  {    go test()    go test()    <-ch    <-ch}

对于channel类似于linux中的管道,信道可以分为无缓冲的和有缓冲的.对于无缓冲的放了数据就需要取出,否则阻塞;对于有缓冲的信道,可以存储对应大小的数据,满了以后就在存数据就类似于非阻塞的,会发生阻塞.
eg: ch := make(chan type, value)

二.go中的并行
对于上面的例子,输出结果跟串行结果一样,why??
因为Go默认所有的goroutine只能在一个线程里(单核)跑.而一个goroutine不阻塞是不会把CPU让让给其他goroutine的.所以执行结果类似于串行.

对于Go中的并行可以使用runtime包中的函数:

func test(){    for i:=0; i<10 ;i++{        fmt.Print(i)    }    ch<-0}func main()  {    //使用两个核    runtime.GOMAXPROCS(2)    go test()    go test()    <-ch    <-ch}

上面会抢占式输出
在多核情况下,如果一个goroutine发生阻塞,其他goroutine会在另一个线程(核)上执行