协程间通信

参考解析

题目来源:一点资讯

答案:

协程通信机制——Future,Channel与Pub/Sub

  1. 在许多的现代异步IO框架中,调度的基本单位是协程(Coroutine)。与多线程不同,协程使用程序自定义的调度器进行调度,因此更容易控制协程之间的执行顺序,要想充分利用协程的调度模型,有一个趁手的通信机制是很重要的。它主要应该有以下的功能:

​ 能从一个协程发送消息到另一个协程,通知另一个协程特定的事件已经发生能够让协程在事件未发生之前挂起,等待事件发生后被调度并处理,从而有效让出CPU时间能够在消息中附带相应的数据能完成这样任务的模型很多,但是使用的方便程度上则有很大差别,我们主要介绍Channel模型 。

​ 第二种模型是Go语言当中的统一通信模型,它重点解决了Future只能一次性使用的缺点。一个Channel对象好比是一个可以写入信号的管道,一头可以不断写入新的信号,一头则可以不断取出新的信号,写入的信号遵循先进先出的原则,而且信号本身也可以是数据。Channel还有缓冲区大小的限制,如果写入的信号过多而没有人读出则会产生阻塞;同样如果Channel为空而从Channel中读取也会产生阻塞。Go还支持一种特殊的缓冲区大小为0的Channel,比如要求两个协程恰好一个正在尝试写入、一个正在尝试读取才能成功,否则都会产生阻塞。使用Channel模型通信的过程可以如下描述:

通信双方通过某种方式共享一个Channel,比如通过创建协程时当作参数传入;

发送方将要传递的信息写入Channel。如果Channel已满则阻塞。

接收方在需要时从Channel中按先进先出顺序读取数据,如果Channel为空则阻塞。

当Channel不再需要时需要进行关闭。

Channel模型有以下的特点:

可以有多个发送者和多个接收者,实现多对多的关系。多个接收者可以自动实现负载均衡。当接收者不能接收更多信号的时候,发送方也会被阻塞,非常适合实现生产者、消费者模型。

同一个Channel中的信号可以实现可靠的传递,不被取出则不会丢失;而且能保证先进先出。在Go当中可以使用select语句同时等待多个channel,在任意一个可以读取出消息时返回,很容易实现等待多个条件之一发生的逻辑同一个信号只能被接收一次,而不能广播给多个接收者,这是Channel模型的一个缺点,要实现广播给多个接收者,需要维护一个Channel的列表,由专门的逻辑负责将信号复制并发送给多个接收者。

参考地址:https://zhuanlan.zhihu.com/p/22092214