go channel基本使用
发布时间:2023-10-19 12:35:57 所属栏目:语言 来源:
导读:Go 程序在并发处理一些任务的时,会为每一个任务创建一个 goroutine,然后需要根据不同的 goroutine 的返回的结果做不同的处理。
如果按照通常的做法,分别获取每个 channel 的结果:
taskCh1 := make(chan bool
如果按照通常的做法,分别获取每个 channel 的结果:
taskCh1 := make(chan bool
Go 程序在并发处理一些任务的时,会为每一个任务创建一个 goroutine,然后需要根据不同的 goroutine 的返回的结果做不同的处理。 如果按照通常的做法,分别获取每个 channel 的结果: taskCh1 := make(chan bool) taskCh2 := make(chan bool) taskCh3 := make(chan bool) go run(taskCh1) go run(taskCh2) go run(taskCh3) for { // 接收通道 1 的结果 result1 := <-taskCh1 // 接收通道 2 的结果 result2 := <-taskCh2 // 接收通道 3 的结果 result3 := <-taskCh3 } 然后再根据不同 goroutine 返回的结果做后续的处理,这个代码有个问题,需要等待所有的 goroutine 都执行完成之后才能做出结果,这样实现的效率很低,因为每一个获取 channel 值的过程都是阻塞的。 在处理多个通道时,想同时接收多个通道的数据将会变的很困难。 而且在一些情况下,需要根据先返回通道的做出不同的处理,上面那种方式无法做到,这就需要使用多路复用。 Go 提供了 select 机制来解决这个问题。 select 基本使用 select 语法形式和 switch 很相似,switch 接收一个变量,然后根据变量的值做不同的处理,select 操作接收的是通道操作: ch := make(chan int, 1) // 这个例子中,这里必须用缓冲通道 for { select { case <-ch: time.Sleep(time.Second) fmt.Println("case 1 invoke") case data := <-ch: time.Sleep(time.Second) fmt.Printf("case 2 invoke %d\n", data) case ch <- 100: time.Sleep(time.Second) fmt.Println("case3 invoke") } 在 select 的 case 中,可以执行三种操作: <- ch:接收通道,但是对值不处理 data := <-ch:接收通道,并处理从通道中得到的结果 ch <- 100:向通道中发送数据 上面的程序运行起来之后,case 3 会首先执行,然后 case1 和 case2 会随机执行一个,程序就这样一直交替运行下去。 如果用 select 改造上面第一个例子中的代码,就是下面这样: for { select { // 接收通道 1 的结果 case r := <-taskCh1: fmt.Printf("task1 result %+v\n", r) // 接收通道 2 的结果 case r := <-taskCh2: fmt.Printf("task2 result %+v\n", r) // 接收通道 3 的结果 case r := <-taskCh3: fmt.Printf("task3 result %+v\n", r) } } select 会及时响应每一个就绪的 channel,无论是发送数据还是接收数据。 (编辑:马鞍山站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
推荐文章
站长推荐