Ai
1 Star 0 Fork 0

码农兴哥/go-demo-2025

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
main5_1.go 2.16 KB
一键复制 编辑 原始数据 按行查看 历史
renxing 提交于 2025-12-19 16:10 +08:00 . Go语言条件变量sync.Cond用法示例
package main
import (
"fmt"
"sync"
"time"
)
/**
## 条件变量的高级用法
### 超时等待的实现
**使用场景**:有时候我们不想无限期地等待条件成立,而是希望在指定时间内等待,超时后执行其他操作。
**注意事项**:
- 标准sync.Cond不支持超时
- 需要结合select和time.After实现
- 需要注意goroutine泄漏问题
这段代码有goroutine泄漏的风险,因为超时后无法取消已经调用的cond.Wait()。
这段代码仅供演示,在实际应用中,需要使用更复杂的技术(参考 main5_2.go)。
*/
// CondWithTimeout 支持超时的条件变量
type CondWithTimeout struct {
cond *sync.Cond
}
func (cwt *CondWithTimeout) WaitWithTimeout(timeout time.Duration) bool {
// 创建一个通知通道
ch := make(chan struct{})
// 启动一个goroutine来等待条件变量
go func() {
cwt.cond.L.Lock()
defer cwt.cond.L.Unlock()
cwt.cond.Wait()
ch <- struct{}{}
}()
// 等待条件变量或超时
select {
case <-ch:
return true // 条件满足
case <-time.After(timeout):
// 超时,需要取消等待
cwt.cond.L.Lock()
defer cwt.cond.L.Unlock()
// 这里无法真正取消Wait,但可以设置一个标志让goroutine在唤醒后立即退出
// 在实际应用中,可能需要更复杂的机制
return false
}
}
func timeoutExample() {
fmt.Println("=== 超时等待示例 ===")
var mu sync.Mutex
cond := sync.NewCond(&mu)
cwt := &CondWithTimeout{cond: cond}
var condition bool
// 等待者
go func() {
mu.Lock()
defer mu.Unlock()
fmt.Println("等待者: 开始等待(最多2秒)")
if cwt.WaitWithTimeout(2 * time.Second) {
if condition {
fmt.Println("等待者: 条件满足")
} else {
fmt.Println("等待者: 被唤醒但条件不满足")
}
} else {
fmt.Println("等待者: 等待超时")
}
}()
// 条件设置者(故意延迟3秒,超过等待时间)
go func() {
time.Sleep(3 * time.Second)
mu.Lock()
condition = true
fmt.Println("设置者: 设置条件为true")
mu.Unlock()
cond.Signal()
fmt.Println("设置者: 发送信号")
}()
time.Sleep(4 * time.Second)
}
func main() {
timeoutExample()
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/rxbook/go-demo-2025.git
git@gitee.com:rxbook/go-demo-2025.git
rxbook
go-demo-2025
go-demo-2025
master

搜索帮助