MST

星途 面试题库

面试题:Go中select语句在并发测试时如何处理多个通道操作

请描述在Go语言中,使用select语句进行并发测试时,若同时有多个通道操作(如读或写)准备好,select语句的执行逻辑是怎样的?并举例说明如何利用这一特性进行简单的并发任务调度。
39.0万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

select语句执行逻辑

在Go语言中,当select语句中有多个通道操作(读或写)准备好时:

  1. 随机选择select会随机选择一个准备好的通道操作来执行。这种随机选择机制避免了某个通道操作总是被优先执行的“饥饿”问题。
  2. 阻塞:如果没有任何通道操作准备好,select语句会阻塞,直到至少有一个通道操作准备好。
  3. 默认分支:如果有default分支,当没有其他通道操作准备好时,default分支会立即执行,select语句不会阻塞。

并发任务调度示例

以下是一个简单的示例,展示如何利用select语句进行并发任务调度:

package main

import (
    "fmt"
    "time"
)

func task1(ch chan string) {
    time.Sleep(2 * time.Second)
    ch <- "Task 1 completed"
}

func task2(ch chan string) {
    time.Sleep(1 * time.Second)
    ch <- "Task 2 completed"
}

func main() {
    ch1 := make(chan string)
    ch2 := make(chan string)

    go task1(ch1)
    go task2(ch2)

    select {
    case result := <-ch1:
        fmt.Println(result)
    case result := <-ch2:
        fmt.Println(result)
    }
}

在上述示例中:

  1. 启动两个并发任务task1task2,分别向ch1ch2通道发送完成信息。
  2. task1会睡眠2秒,task2会睡眠1秒。
  3. select语句会随机选择一个准备好的通道操作执行。由于task2先完成,通常情况下会先打印Task 2 completed。但如果多次运行,也有可能出现打印Task 1 completed的情况,这体现了select的随机选择特性。通过这种方式,可以在多个并发任务之间进行调度,优先处理最先完成的任务。