阅读:0

Go语言通道的多路复用——同时处理接收和发送多个通道的数据

多路复用是通信和网络中的一个专业术语。多路复用通常表示在一个信道上传输多路信号或数据流的过程和技术。

提示

报话机同一时刻只能有一边进行收或者发的单边通信,报话机需要遵守的通信流程如下:
  • 说话方在完成时需要补上一句“完毕”,随后放开通话按钮,从发送切换到接收状态,收听对方说话。
  • 收听方在听到对方说“完毕”时,按下通话按钮,从接收切换到发送状态,开始说话。

电话可以在说话的同时听到对方说话,所以电话是一种多路复用的设备,一条通信线路上可以同时接收或者发送数据。同样的,网线、光纤也都是基于多路复用模式来设计的,网线、光纤不仅可支持同时收发数据,还支持多个人同时收发数据。

在使用通道时,想同时接收多个通道的数据是一件困难的事情。通道在接收数据时,如果没有数据可以接收将会发生阻塞。虽然可以使用如下模式进行遍历,但运行性能会非常差。
for{
    // 尝试接收ch1通道
    data, ok := <-ch1
    // 尝试接收ch2通道
    data, ok := <-ch2
    // 接收后续通道
    …
}
Go 语言中提供了 select 关键字,可以同时响应多个通道的操作。select 的每个 case 都会对应一个通道的收发过程。当收发完成时,就会触发 case 中响应的语句。多个操作在每次 select 中挑选一个进行响应。格式如下:

select{
    case 操作1:
        响应操作1
    case 操作2:
        响应操作2
    …
    default:
        没有操作情况
}

  • 操作1、操作2:包含通道收发语句,请参考下表。

    select 多路复用中可以接收的样式
    操   作 语句示例
    接收任意数据 case <- ch;
    接收变量 case d :=  <- ch;
    发送数据 case ch <- 100;
  • 响应操作1、响应操作2:当操作发生时,会执行对应 case 的响应操作。
  • default:当没有任何操作时,默认执行 default 中的语句。

select 的详细使用方法,请参考下节的示例。