在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
协程间通信协程中可以使用共享变量来通信,但是很不提倡这样做,因为这种方式给所有的共享内存的多线程都带来了困难。 在 Go 中有一种特殊的类型,通道(channel),就像一个可以用于发送类型化数据的管道,由其负责协程之间的通信,从而避开所有由共享内存导致的陷阱;这种通过通道进行通信的方式保证了同步性。 数据在通道中进行传递:在任何给定时间,一个数据被设计为只有一个协程可以对其访问,所以不会发生数据竞争。数据的所有权(可以读写数据的能力)也因此被传递。 通道服务于通信的两个目的:值的交换,同步的,保证了两个计算(协程)任何时候都是可知状态。 声明与初始化通道的声明格式如下:
未初始化的通道的值为 nil。 通道也是引用类型,所以我们使用 make() 函数来给它分配内存。
通信操作符操作符
下面的例子展示了两个协程之间的通信:
输出结果: 在 main() 方法的最后一行中,使用了 time 包中的 sleep 函数来暂停1秒,以确保 main() 方法会在另个两个协程之后结束,如果不在 main() 方法中等待,协程会随着程序的结束而消亡。 通道阻塞默认情况下,通信是同步且无缓冲的,通道的发送/接收操作在对方准备好之前都是阻塞的:
现在我们把上面的例子修改一下,去掉 sendData() 方法前的 go 关键字:
输出结果: 运行程序后出错了,抛出了一个 panic,这是为什么呢? 这是因为 Go 程序在运行时会检查所有的协程,查找是否存在有阻塞(读取或者写入某个通道)的情况。 而上面这段代码中的 sendData() 方法阻塞了 main() 方法,导致 如果我们接着再修改一下代码,保留 sendData() 方法的关键字,而去掉 getData() 方法的关键字:
因为发送和接收操作都会被执行,所以结果是正常输出“golang”。 通信是一种同步形式:通过通道,两个协程在通信(协程会和)中某刻同步交换数据。无缓冲通道成为了多个协程同步的完美工具。 带缓冲的通道一个无缓冲通道只能包含 1 个元素,但是我们可以为通道提供了一个缓存,来扩展通道可容纳的元素个数。 在 make() 函数中设置容量:
如果容量大于 0,通道就是异步的了:缓冲满载(发送)或者变空(接收)之前通信不会阻塞,元素会按照发送的顺序被接收。如果容量是 0 或者未设置,通信仅在收发双方准备好的情况下才可以成功。 |
请发表评论