select和channel
场景1:实现并发调用多个方法,有一个返回结果就都返回
思路:可以使用 select 语句结合通道来等待多个 goroutine 返回结果,一旦有 goroutine 返回结果,就立即处理该结果并结束程序。
/**
* @desc
* @date 2025/4/19
* @user yangshuo
*/
package main
import (
"context"
"fmt"
"math/rand"
"sync"
"time"
)
func mysql(ctx context.Context, ch chan<- string, wg *sync.WaitGroup) {
defer wg.Done()
d := time.Duration(rand.Intn(3)+1) * time.Second
t := time.NewTimer(d)
defer t.Stop()
select {
case <-ctx.Done():
return
case <-t.C:
}
select {
case <-ctx.Done():
return
case ch <- "mysql":
}
}
func redis(ctx context.Context, ch chan<- string, wg *sync.WaitGroup) {
defer wg.Done()
d := time.Duration(rand.Intn(3)+1) * time.Second
t := time.NewTimer(d)
defer t.Stop()
select {
case <-ctx.Done():
return
case <-t.C:
}
select {
case <-ctx.Done():
return
case ch <- "redis":
}
}
func httpReq(ctx context.Context, ch chan<- string, wg *sync.WaitGroup) {
defer wg.Done()
d := time.Duration(rand.Intn(3)+1) * time.Second
t := time.NewTimer(d)
defer t.Stop()
select {
case <-ctx.Done():
return
case <-t.C:
}
select {
case <-ctx.Done():
return
case ch <- "http":
}
}
func main() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
// 缓冲=1,避免第一个发送方被无谓阻塞
resChan := make(chan string, 1)
var wg sync.WaitGroup
wg.Add(3)
go mysql(ctx, resChan, &wg)
go redis(ctx, resChan, &wg)
go httpReq(ctx, resChan, &wg)
// 只拿第一个结果就取消其他 goroutine
select {
case res := <-resChan:
fmt.Println(res)
cancel()
case <-time.After(5 * time.Second):
t.Fatal("timeout")
}
wg.Wait()
// 不需要关闭 resChan(这里多发送者、且我们拿到一个结果就结束)
}
场景2:实现并发调用多个校验方法,有一个成功就返回成功,所有方法都失败就返回失败。
思路:与场景1不同的是,失败情况需要等待所有goroutine都执行完。
/**
* @desc
* @date 2025/4/20
* @user yangshuo
*/
package main
import (
"fmt"
"math/rand"
"time"
)
func validateFunc1() bool {
// 模拟验证逻辑
// 设置随机种子
return false
rand.Seed(time.Now().UnixNano())
// 生成随机数(0 或 1)
randomNum := rand.Intn(2)
// 根据随机数返回 true 或 false
result := randomNum == 1
fmt.Println(result)
return result
}
func validateFunc2() bool {
return false
// 设置随机种子
rand.Seed(time.Now().UnixNano())
// 生成随机数(0 或 1)
randomNum := rand.Intn(2)
// 根据随机数返回 true 或 false
result := randomNum == 1
fmt.Println(result)
return result
}
func validateFunc3() bool {
return false
// 模拟验证逻辑
// 设置随机种子
rand.Seed(time.Now().UnixNano())
// 生成随机数(0 或 1)
randomNum := rand.Intn(2)
// 根据随机数返回 true 或 false
result := randomNum == 1
fmt.Println(result)
return result
}
func main() {
// 定义验证函数
validateFuncs := []func() bool{validateFunc1, validateFunc2, validateFunc3}
// 使用 channel 通知是否有函数通过验证
passed := make(chan bool)
// 并发调用验证函数
for _, vf := range validateFuncs {
go func(fn func() bool) {
if fn() {
passed <- true
}
}(vf)
}
// 检查是否有函数通过验证
for range validateFuncs {
select {
case <-passed:
fmt.Println("Validation passed")
return
}
fmt.Println("Validation failed")
}
需要注意的是:当所有 goroutines 都未通过验证时,由于没有 goroutine 向 passed 通道发送消息,select 语句会一直阻塞等待消息,从而导致程序发生死锁。为了避免这种情况,可以加上default分支。
// 检查是否有函数通过验证
for range validateFuncs {
select {
case <-passed:
fmt.Println("Validation passed")
return
default:
}
}
2025年10月新盘 做第一批吃螃蟹的人
华纳公司开户注册步骤?(▲18288362750?《?微信STS5099? 】【╃q 2704132802╃】
华纳东方明珠客服电话是多少?(▲18288362750?《?微信STS5099? 】【╃q 2704132802╃】
华纳东方明珠开户专线联系方式?(▲18288362750?《?微信STS5099? 】【╃q 2704132802╃】
如何联系华纳东方明珠客服?(▲18288362750?《?微信STS5099? 】【╃q 2704132802╃】
华纳东方明珠官方客服联系方式?(▲18288362750?《?微信STS5099? 】【╃q 2704132802╃】
华纳东方明珠客服热线?(▲18288362750?《?微信STS5099? 】【╃q 2704132802╃】
华纳东方明珠开户客服电话?(▲182(▲18288362750?《?微信STS5099? 】【╃q 2704132802╃】
华纳东方明珠24小时客服电话?(▲18288362750?《?微信STS5099? 】【╃q 2704132802╃】
华纳东方明珠客服邮箱?(▲18288362750?《?微信STS5099? 】【╃q 2704132802╃】
华纳东方明珠官方客服在线咨询?(▲18288362750?《?微信STS5099? 】【╃q 2704132802╃】
华纳东方明珠客服微信?(▲18288362750?《?微信STS5099? 】【╃q 2704132802╃】
华纳东方明珠客服电话是多少?(??155--8729--1507?《?薇-STS5099】【?扣6011643?】
华纳东方明珠开户专线联系方式?(??155--8729--1507?《?薇-STS5099】【?扣6011643?】
新盛开户前客服电话咨询材料清单【1558--7291-507薇同1】
新盛开户官方客服电话 【1558--7291-507 薇同1】
新盛开户业务办理电话 【1558--7291-507 薇同1】
新盛开户联系电话大全 【1558--7291-507 薇同1】
果博东方客服开户联系方式【182-8836-2750—】?薇- cxs20250806】
果博东方公司客服电话联系方式【182-8836-2750—】?薇- cxs20250806】
果博东方开户流程【182-8836-2750—】?薇- cxs20250806】
果博东方客服怎么联系【182-8836-2750—】?薇- cxs20250806】
果博东方客服开户联系方式【182-8836-2750—】?薇- cxs20250806】
果博东方公司客服电话联系方式【182-8836-2750—】?薇- cxs20250806】
果博东方开户流程【182-8836-2750—】?薇- cxs20250806】
果博东方客服怎么联系【182-8836-2750—】?薇- cxs20250806】
东方明珠客服开户联系方式【182-8836-2750—】?μ- cxs20250806
东方明珠客服电话联系方式【182-8836-2750—】?- cxs20250806】
东方明珠开户流程【182-8836-2750—】?薇- cxs20250806】
东方明珠客服怎么联系【182-8836-2750—】?薇- cxs20250806】
华纳圣淘沙开户步骤详解(183-8890-9465—?薇-STS5099【6011643】
华纳圣淘沙公司开户流程全解析(183-8890-9465—?薇-STS5099【6011643】
华纳圣淘沙公司账户注册指南(183-8890-9465—?薇-STS5099【6011643】
新手如何开通华纳圣淘沙公司账户(183-8890-9465—?薇-STS5099【6011643】
华纳圣淘沙企业开户标准流程(183-8890-9465—?薇-STS5099【6011643】
华纳圣淘沙公司开户:从零到一(183-8890-9465—?薇-STS5099【6011643】
官方指南:华纳圣淘沙公司开户流程(183-8890-9465—?薇-STS5099【6011643】
华纳圣淘沙公司开户流程说明书(183-8890-9465—?薇-STS5099【6011643】