学习笔记:channel的初步理解

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

channel会阻塞,阻塞的时候系统会继续顺序调用其他goroutine,main()也是一个goroutine,只是最先被执行。

看一个代码:

package main

import (
    "fmt"
)

func display(msg string, c chan bool) {
    fmt.Println(msg)
    c <- true
    fmt.Printf("end %s \n", msg)
}

func main() {
    c := make(chan bool)
    go display("hello", c)
    go display("hello1", c)
    go display("hello2", c)
    fmt.Println("start")
    <-c
    fmt.Println("end")
}

这段代码输出结果:

start
hello
end hello
hello1
hello2
end

首先执行main函数,它是第一个goroutine,在main中又通过go语句创建了3个goroutine,但是不是立即执行的,它们必须等到main挂起后才会被调用。
当main执行到 <-c 的时候,根据channel特性,此时产生了阻塞,这时候系统会将main的goroutine挂起,继续调用其他goroutine,也就是先前创建的3个goroutine,从第一个开始。
执行到:go display(“hello”, c)
这时候首先打印出hello,随机函数中 c <- true 因为main已经在等待接受,所以这里发送成功,继续执行下面的代码即打印出end hello,同时由于接受者main也接收到了信息,main的goroutine阻塞取消,被激活,可被继续调用。
但这时候不会立即调用main的,因为虽然main被重新激活了,但是它已经被排到剩下两个goroutine后面了,所以接下来实际上继续执行的goroutine是 go display(“hello1”, c) 。
在 go display(“hello1”, c) 中,hello1首先被打印出来,随机 c <- true 像channel中发送消息,但是由于没有接收者(main已经接收过了),所以这个goroutine也被阻塞,系统继续调用下一个goroutine,同理只输出hello2,最后再调用main的goroutine,打印出end。

以上是无缓冲的channel,有缓冲的阻塞原理与这个不一样。


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

本文来自:开源中国博客

感谢作者:吾爱

查看原文:学习笔记:channel的初步理解

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

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