并发编程
并发编程
基本原则
- 控制临界区的纯度
- 控制临界区的粒度
- 减少临界区代码的执行时间
- 避免长时间持有互斥量
- 优先使用原子操作而不是互斥量
uint32 是原子操作方法支持的最短数值类型,可用于节省计数器的空间
超时控制
使用 context 包对多个 G 进行超时优雅退出
不额外启用 G 的情况下实现超时判断? 使用 CAS 操作比较是否为原状态,如果超时,状态会被修改至其他状态,否则就没有超时
一个容易犯的错误:在 for-select 结构里面使用 <-time.After(),这会导致内存泄露,因为在计时器触发之前,GC并不会回收 timer!
func ProcessChannelMessages(ctx context.Context, in <-chan string, idleCounter prometheus.Counter) {
idleDuration := 5 * time.Minute
idleDelay := time.NewTimer(idleDuration)
// 记得停止定时器
defer idleDelay.Stop()
for {
// 在时间过期后重置并激活同一定时器
idleDelay.Reset(idleDuration)
select {
case s, ok := <-in:
if !ok {
return
}
// 等待定时器超时
case <-idleDelay.C:
idleCounter.Inc()
case <-ctx.Done():
return
}
}
}