2 回答

TA貢獻(xiàn)1725條經(jīng)驗(yàn) 獲得超8個(gè)贊
由于您所做的只是鎖定單個(gè)計(jì)數(shù)器,因此您可以簡(jiǎn)化并僅使用sync/atomic包。AddInt32(&x, 1)
在啟動(dòng) goroutine 和AddInt32(&x, -1)
結(jié)束時(shí)調(diào)用。從您的繪圖 goroutine調(diào)用LoadInt32(&x)
。

TA貢獻(xiàn)1831條經(jīng)驗(yàn) 獲得超4個(gè)贊
它依賴于用例(你可以選擇你想要的,并且在你產(chǎn)生錯(cuò)誤或達(dá)到性能損失之前沒有人關(guān)心),通道將 Lock 隱藏在里面并使編碼更簡(jiǎn)單,但性能成本很小 - 所以我建議使用通道對(duì)于一般用例,除非您正在考慮更高的性能):
在以下情況下使用通道:
1 - 轉(zhuǎn)讓所有權(quán)
2 - 協(xié)調(diào)
在以下情況下使用基元:
3 -性能關(guān)鍵
4 - 保護(hù)結(jié)構(gòu)
引用的內(nèi)部狀態(tài):第 33 頁
由于您使用的是協(xié)調(diào) goroutine 數(shù)量的軟實(shí)時(shí) UI,而不是性能關(guān)鍵代碼,因此我建議使用通道,我在此示例中簡(jiǎn)化了您的代碼:
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 關(guān)注
- 178 瀏覽
添加回答
舉報(bào)