切换导航
{{systemName}}
{{ info.Title }}
{{info.Title}}
{{ menu.Title }}
{{menu.Title}}
登录
|
退出
搜索
为 sync.WaitGroup 中Wait函数支持 WaitTimeout 功能.
作者:ych
```go package main import ( "fmt" "sync" "time" ) func main() { wg := sync.WaitGroup{} c := make(chan struct{}) for i := 0; i < 10; i++ { wg.Add(1) go func(num int, close <-chan struct{}) { defer wg.Done() <-close fmt.Println(num) }(i, c) } if WaitTimeout(&wg, time.Second*5) { close(c) fmt.Println("timeout exit") } time.Sleep(time.Second * 10) } func WaitTimeout(wg *sync.WaitGroup, timeout time.Duration) bool { // 要求手写代码 // 要求sync.WaitGroup支持timeout功能 // 如果timeout到了超时时间返回true // 如果WaitGroup自然结束返回false } ``` **解析** 首先 `sync.WaitGroup` 对象的 `Wait` 函数本身是阻塞的,同时,超时用到的`time.Timer` 对象也需要阻塞的读。 同时阻塞的两个对象肯定要每个启动一个协程,每个协程去处理一个阻塞,难点在于怎么知道哪个阻塞先完成。 目前我用的方式是声明一个没有缓冲的`chan`,谁先完成谁优先向管道中写入数据。 ```go package main import ( "fmt" "sync" "time" ) func main() { wg := sync.WaitGroup{} c := make(chan struct{}) for i := 0; i < 10; i++ { wg.Add(1) go func(num int, close <-chan struct{}) { defer wg.Done() <-close fmt.Println(num) }(i, c) } if WaitTimeout(&wg, time.Second*5) { close(c) fmt.Println("timeout exit") } time.Sleep(time.Second * 10) } func WaitTimeout(wg *sync.WaitGroup, timeout time.Duration) bool { // 要求手写代码 // 要求sync.WaitGroup支持timeout功能 // 如果timeout到了超时时间返回true // 如果WaitGroup自然结束返回false ch := make(chan bool, 1) go time.AfterFunc(timeout, func() { ch <- true }) go func() { wg.Wait() ch <- false }() return <- ch } ```
相关推荐
golang 中解析 tag 是怎么实现的?反射原理是什么?(中高级肯定会问,比较难,需要自己多去总结)
使用gorm不当出现too Many Connections的问题
golang map 使用注意的点,是否并发安全?
uint 类型溢出问题
Golang中defer和return执行的先后顺序
golang中两个变量值的4种交换方式
讲讲 Go 的 select 底层数据结构和一些特性?(难点,没有项目经常可能说不清,面试一般会问你项目中怎么使用select)
golang进行封包和拆包的完整解决方案
golang orm框架 gorm
Golang空结构体 struct{} 的使用
调用函数传入结构体时,应该传值还是指针? (Golang 都是传值)
对已经关闭的 chan 进行读写,会怎么样?为什么?
Golang判断slice是否相等
序列化协议
讲讲 Go 的 defer 底层数据结构和一些特性?
golang面试题
go defer,多个 defer 的顺序,defer 在什么时机会修改返回值?
Golang 单引号,双引号,反引号的区别?
B+树为什么快
什么是死锁?死锁产生的原因?如何避免死锁?
golang并发题目测试
交替打印数字和字母
for range 的时候它的地址会发生变化么?
机器人坐标问题
数组和切片的区别 (基本必问)
昨天那个在for循环里append元素的同事,今天还在么?
复利计算 递归/非递归
单例模式的应用场景
实现阻塞读且并发安全的map
Redis的优点
在 golang 协程和channel配合使用
Golang表示枚举类型的详细讲解
常见语法题目1
讲讲 Go 的 slice 底层数据结构和一些特性?
MySQL索引原理
常见语法题目2
写出以下逻辑,要求每秒钟调用一次proc并保证程序不退出?
判断两个给定的字符串排序后是否一致
高并发下的锁与map的读写
golang 中 make 和 new 的区别?(基本必问)
redis缓存穿透、缓存击穿、缓存雪崩原因+解决方案
消息队列使用的场景介绍
golang 实现一个负载均衡案例(随机,轮训)
ElasticSearch使用场景
操作系统基本原理
字符串替换问题
七道语法找错题目
判断字符串中字符是否全都不同
redis在项目中的使用
翻转字符串
基本数据结构和算法
TiDB使用场景
评论区
先去登录
版权所有:机遇屋在线 Copyright © 2021-2025 jiyuwu Co., Ltd.
鲁ICP备16042261号-1