Golang / 未分类 · 2023年3月7日 0

关于Golang的那些事(七)– goroutine和通道【】

Go有两种并发编程的风格。这一章展示goroutine和通道(channel),它们支持通信顺序进程,CSP是一个并发的模式,在不同的执行体直接传递值,但是变量本身局限于单一的执行体。Go的长处是处理并发请求,并发编程在本质上比顺序编程要困难一些,从顺序编程的直觉让我们觉得贼迷茫。

在Go里面,每一个并发执行的活动成为goroutine。假设有一个程序,它有两个函数,一个是用来做计算,一个是用来做打印,他们互不调用,于是他们可以同时执行,可以在两个goroutine的并发程序中。当一个程序启动时,只有一个goroutine来调用main函数,称它为主goroutine。新的goroutine通过go语句进行创建。语法上,一个go语句是在普通的函数或者方法调用前加上go关键字前缀。go语句使函数在一个新创建的goroutine中调用。go语句本身的执行立即完成:

f(); // 调用f(),等待它返回

go f();// 新建一个调用f()的goroutine,不用等待

我们拿计算45个斐波那契数为例子,因为它使用非常低效的递归算法,所以需要大量的时间来计算。

func main(){

   go spinner(100 * time.Millisecond)

  const n = 45

  fibN := fib(n) //  slow

  fmt.Printf("rFibonacci(%d) = %d", n ,fibN)

}

func spinner (delay time.Duration) {

 for {

   for _, r:=range `-|/`  {

      fmt.Printf("r%c", r);

     time.Sleep(delay)

  }

 }

}

func fib(x int) int {

  if x

     return  x

  }

  return fib(x - 1) + fib(x - 2)

}

如果说goroutine是Go程序并发的执行体,通道就是它们之间的连接。通道是可以让一个goroutine发送特定值到另一个goroutine的通信机制。每一个通道是一个具体类型的导管,叫做通道的元素类型。一个有int类型元素的通道写作chan int,使用内置的make函数来创建一个通道的方法:

ch := make(chan int)// ch的类型是chan int

像map一样,通道是一个使用make创建的数据结构的引用,当复制或者作为参数传递到一个函数的时候,复制的是引用,这样调用者和被调用者都引用同一个数据的数据结构。和其他引用类型一样,通道的零值是nil。同种类型的通道可以使用==符号进行比较。当二者都是同一通道数据的引用时,比较值为true。通道也可以和nil进行比较。通道的两个主要操作是发送和接收,两者统称为通信。send语句从一个goroutine传输一个值到另外一个在执行接收表达式的goroutine。两个操作都使用

ch

x =

通道还支持第三个操作:关闭,它设置一个标志位来指示当前已经发送完毕,这个通道后面就没有值了,关闭后的发送操作会导致宕机,调用的方法为:

close(ch)

使用简单的make调用创建的通道叫做无缓冲通道,但make还可以接受第二个可选参数,一个表示通道容量的整数,如果容量是0,make创建一个无缓冲通道:

ch  = make (chan int) //无缓冲通道

ch = make (chan int, 0) // 无缓冲通道

ch = make (chan int, 3) // 容量为3的缓冲通道
打赏 赞(0) 分享'
分享到...
微信
支付宝
微信二维码图片

微信扫描二维码打赏

支付宝二维码图片

支付宝扫描二维码打赏