1 回答

TA貢獻(xiàn)1770條經(jīng)驗(yàn) 獲得超3個(gè)贊
您應(yīng)該完成圍棋之旅,并特別關(guān)注圍棋例程以及查看等待組。我將在這里簡(jiǎn)要介紹適用的概念。
關(guān)鍵字go
在Go中,同時(shí)運(yùn)行函數(shù)非常容易。鑒于以下代碼,我只需要在 前面添加前綴,使其與程序的其余部分同時(shí)運(yùn)行。go
blockingCode
func blockingCode() {
time.Sleep(time.Second)
fmt.Println("finishing blocking")
}
func main() {
fmt.Println("starting main")
go blockingCode()
fmt.Println("finishing main")
}
你會(huì)注意到關(guān)于這一點(diǎn)的幾件事:
如果我刪除了前綴,該函數(shù)將被阻止,您將看到所有三個(gè)打印語(yǔ)句,最后兩個(gè)比第一個(gè)打印語(yǔ)句晚一秒(去游樂(lè)場(chǎng))。
go
如果我重新添加前綴,該函數(shù)不會(huì)阻塞,但您不會(huì)看到 print 語(yǔ)句。這是因?yàn)橹骱瘮?shù)(主 go 例程)在完成之前終止。這就是等待組發(fā)揮作用的地方。
go
fmt.Println("finishing blocking")
blockingCode
WaitGroup
要等待多個(gè)戈魯丁完成,我們可以使用一個(gè)等待組。https://gobyexample.com/waitgroups。
將等待組視為原子計(jì)數(shù)器,其中調(diào)用阻塞直到計(jì)數(shù)器為 0。生成 go 例程時(shí),會(huì)遞增計(jì)數(shù)器 (),在完成 go 例程時(shí),會(huì)取消遞增計(jì)數(shù)器 ()。下面是支持等待組的代碼。去游樂(lè)場(chǎng)wg.Wait
wg.Add
wg.Done
func blockingCode(wg *sync.WaitGroup) {
defer wg.Done()
time.Sleep(time.Second)
fmt.Println("finishing blocking")
}
func main() {
wg := sync.WaitGroup{}
fmt.Println("starting main")
wg.Add(1)
go blockingCode(&wg)
wg.Wait()
fmt.Println("finishing main")
}
現(xiàn)在,這會(huì)產(chǎn)生與我們上面看到的完全相同的行為 - 該函數(shù)將阻塞,您將看到所有三個(gè)print語(yǔ)句,最后兩個(gè)比第一個(gè)延遲一秒鐘打印 - 那么為什么我們首先將其并發(fā)?不同之處在于,我們現(xiàn)在可以同時(shí)運(yùn)行許多事情,而不是按順序運(yùn)行很多事情。在這種情況下,我們沒(méi)有看到并發(fā)的好處的原因是因?yàn)槲覀冎煌瑫r(shí)做一件事。
讓我們調(diào)整示例以運(yùn)行多次。您會(huì)注意到,腳本運(yùn)行所需的時(shí)間幾乎相同,即使我們調(diào)用的 blockCode 需要整整一秒鐘才能運(yùn)行,三次,如果我們刪除關(guān)鍵字和等待組,我們會(huì)看到此代碼至少需要三秒鐘才能運(yùn)行 go Playground。blockingCodego
func blockingCode(wg *sync.WaitGroup) {
defer wg.Done()
time.Sleep(time.Second)
fmt.Println("finishing blocking")
}
func main() {
wg := sync.WaitGroup{}
fmt.Println("starting main")
wg.Add(1)
go blockingCode(&wg)
wg.Add(1)
go blockingCode(&wg)
wg.Add(1)
go blockingCode(&wg)
wg.Wait()
fmt.Println("finishing main")
}
您的示例
您選擇如何處理并發(fā)行為很大程度上取決于應(yīng)用程序的細(xì)節(jié),但是像這樣的東西應(yīng)該實(shí)現(xiàn)我在這里提供的并發(fā)概念,并允許您與加載程序同時(shí)運(yùn)行監(jiān)視器。
func main() {
// ...
wg := sync.WaitGroup{}
for a := 0; a < len(j)/2; a++ {
cpucore := j[a]
wg.Add(1)
go runCpuLoader(&wg, sampleInterval, cpuload, duration, cpucore)
}
wg.Wait()
}
func runCpuLoader(wg *sync.WaitGroup, sampleInterval time.Duration, cpuload float64, duration float64, cpu int) {
defer wg.Done()
// ...
}
- 1 回答
- 0 關(guān)注
- 105 瀏覽
添加回答
舉報(bào)