Golang -- goroutine (一)

来源:互联网 发布:mac如何隐藏照片 编辑:程序博客网 时间:2024/05/18 01:56

介绍

goroutine是Go并行设计的核心。goroutine说到底其实就是线程,但是它比线程更小,十几个goroutine可能体现在底层就是五六个线程。Go语言内部帮你实现了这些goroutine之间的内存共享。执行goroutine只需极少的栈内存(大概是4~5KB),当然会根据相应的数据伸缩。也正因为如此,可同时运行成千上万个并发任务。goroutine比thread更易用、更高效、更轻便。
—–摘自《Go Web编程》

使用

go 和 channel

为了使goroutine之间可以共享数据,有两种实现方式,一种是使用共享变量,通过加锁和解锁实现。另一种是使用通信的方式。
如果启动了A, B两个goroutine, B要使用A的某个数据d。A将d放入通道channel中, B先进行自己的运算,然后需要d的时候,从这个channel中获取,当获取不到时,B阻塞在这里,一旦A将d放入channel中, B就开始往下执行。
使用通信的方式比加锁方式更加简单,也更符合人的思考习惯。

go关键字启动gouroutine
make函数创建channel

package mainimport (    "fmt")func main() {    // make函数创建一个可以存放int值的channel    c := make(chan int)    // go关键字启动一个运行say函数的goroutine    go say("hello world", c)    // 从c这个channel中,取出值,c中没有值时,阻塞当前线程。    // 即阻塞主线程,使得其他goroutine可以运行完。    <- c}func say(s string, c chan int) {    for i := 0; i < 5; i++ {        fmt.Println(s)    }    // 将0这个int值放到channel中。    c <- 0}

range 遍历 channel

package mainimport (    "fmt")func main() {    c := make(chan int)    go fabonacci(10, c)    for i := range c {        fmt.Println(i)    }}// 求n以内的斐波那契数列func fabonacci(n int, c chan int) {    x, y := 1, 1    for x < n {        c <- x        x, y = y, x + y    }    // 如果不使用close关闭channel,那么range便利channel的时候会出错    close(c)}

select

select可以监控多个channel,默认是阻塞状态,当某个channel接收或发送数据时,case的语句开始执行。 当多个channel同时接收或发送数据时,select执行顺序是随机的。

package mainimport (    "fmt")func main() {    c := make(chan int)  // 存放斐波那契额数列    quit := make(chan int)  // 控制函数退出    go func() {        // 不断从c中取10次数据        for i := 0; i < 10; i++ {            fmt.Println(<- c)        }        // 控制fabonacci函数退出        quit <- 1    }()    fabonacci(c, quit)    fmt.Println("main exit")}func fabonacci (c, quit chan int) {    x, y := 1, 1    for {        select {        case c <- x:  // 不断向c中塞入数据            x, y = y, x+y        case <- quit:  // quit中被塞入数据后,函数退出            fmt.Println("fabonacci exit")            return        }    }}

select 实现超时

package mainimport (    "fmt"    "time")func main() {    c := make(chan int)    go func() {        for{            select {            case <- c:                fmt.Println("haha")            case <- time.After(time.Second * 3):  // 等待3s后会触发                fmt.Println("超时了")                return            }        }    }()    // 为了防止main退出    o := make(chan int)    <- o}
原创粉丝点击