近期在学习golang的goroutine和channel时候有一些疑惑:

  1. 带缓冲的channel和不带缓冲的channel有什么区别?
  2. goroutine和主进程的有哪些影响和关系?
  3. 多个goroutine的执行顺序是怎么样的?

通过下面的代码我们可以得到答案

第一个例子

  1. 带缓冲的channel和不带缓冲的channel有什么区别?
    没有缓冲的channel必须等到有接收者才会执行后面的代码(阻塞)
  2. goroutine和主进程的有哪些影响和关系?
    主进程如果退出会导致所有的goroutine中断退出。
  3. 多个goroutine的执行顺序是怎么样的?
    多个goroutine会并发执行。

第二个例子

输出:

Washington Tripoli London Beijing tokyo

main() 函数中启动了两个协程:sendData() 通过通道 ch 发送了 5 个字符串,getData() 按顺序接收它们并打印出来。
如果 2 个协程需要通信,你必须给他们同一个通道作为参数才行。

尝试一下如果注释掉 time.Sleep(1e9) 会如何。

我们发现协程之间的同步非常重要:

  • main() 等待了 1 秒让两个协程完成,如果不这样,sendData() 就没有机会输出。
  • getData() 使用了无限循环:它随着 sendData() 的发送完成和 ch 变空也结束了。
  • 如果我们移除一个或所有 go 关键字,程序无法运行,Go 运行时会抛出 panic:
---- Error run E:/Go/Goboek/code examples/chapter 14/goroutine2.exe with code Crashed ---- Program exited with code -2147483645: panic: all goroutines are asleep-deadlock!

为什么会这样?运行时会检查所有的协程(也许只有一个是这种情况)是否在等待(可以读取或者写入某个通道),意味着程序无法处理。这是死锁(deadlock)形式,运行时可以检测到这种情况。

注意:不要使用打印状态来表明通道的发送和接收顺序:由于打印状态和通道实际发生读写的时间延迟会导致和真实发生的顺序不同。