2 回答
TA贡献1725条经验 获得超7个赞
由于您所做的只是锁定单个计数器,因此您可以简化并仅使用sync/atomic包。AddInt32(&x, 1)
在启动 goroutine 和AddInt32(&x, -1)
结束时调用。从您的绘图 goroutine调用LoadInt32(&x)
。
TA贡献1831条经验 获得超4个赞
它依赖于用例(你可以选择你想要的,并且在你产生错误或达到性能损失之前没有人关心),通道将 Lock 隐藏在里面并使编码更简单,但性能成本很小 - 所以我建议使用通道对于一般用例,除非您正在考虑更高的性能):
在以下情况下使用通道:
1 - 转让所有权
2 - 协调
在以下情况下使用基元:
3 -性能关键
4 - 保护结构
引用的内部状态:第 33 页
由于您使用的是协调 goroutine 数量的软实时 UI,而不是性能关键代码,因此我建议使用通道,我在此示例中简化了您的代码:
package main
import (
"fmt"
"math/rand"
"time"
)
func main() {
for i := 0; i < 100; i++ {
go job() // e.g.: run all jobs
}
busy := 0
time.Sleep(10 * time.Millisecond) // or make sure at least on goroutine started
// 10Hz:
tick := time.NewTicker(100 * time.Millisecond)
defer tick.Stop()
for {
select {
case n := <-ch:
busy += n
case <-tick.C:
// forces the UI to redraw all changed screen regions
fmt.Printf(" %d \r", busy)
if busy == 0 {
return
}
}
}
}
func job() {
ch <- +1
time.Sleep(time.Duration(rand.Intn(2000)) * time.Millisecond)
ch <- -1
}
var ch = make(chan int, 1)
- 2 回答
- 0 关注
- 124 浏览
添加回答
举报