关于Golang的那些事(七)-- goroutine和通道

llkevin13579 · · 349 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

       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 < 2 {

     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 // 发送语句

x = <- ch // 赋值语句中的接收表达式

<- ch // 接收语句,丢弃结果

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

close(ch)

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

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

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

ch = make (chan int, 3) // 容量为3的缓冲通道


有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:llkevin13579

查看原文:关于Golang的那些事(七)-- goroutine和通道

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

349 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传