Skip to content

Instantly share code, notes, and snippets.

@barryz
Last active February 12, 2018 10:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save barryz/da1258f7c0a9384b3587b090c9087f62 to your computer and use it in GitHub Desktop.
Save barryz/da1258f7c0a9384b3587b090c9087f62 to your computer and use it in GitHub Desktop.
Go: condition variable broadcast example
package main
import (
"fmt"
"sync"
"time"
)
func main() {
var wg sync.WaitGroup
cv := sync.NewCond(&sync.Mutex{})
done := false
wg.Add(1)
go func() {
defer wg.Done()
fmt.Println("[producer] doing task....")
time.Sleep(3 * time.Second)
fmt.Println("[producer] task done!")
cv.L.Lock()
defer cv.L.Unlock()
done = true // 更改done信号
cv.Broadcast() // 通知给所有等待(阻塞)的goroutine
}()
count := 5
wg.Add(count)
for i := 0; i < count; i++ {
go func(i int) {
defer wg.Done()
fmt.Printf("[consumer:%d] waiting for task done....\n", i)
cv.L.Lock()
defer cv.L.Unlock()
for !done {
// 这里有个需要注意的点: 在这里当前goroutine已经拿到锁了, 为什么producer的goroutine还能拿到锁?
// 原因:进入Wait()函数后, 会有解锁操作, 离开Wait()后会重新加锁
cv.Wait() // 等待被broadcast goroutine唤醒
fmt.Printf("[consumer:%d] task done!\n", i)
}
}(i)
}
wg.Wait()
fmt.Println("[main] goroutine done!")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment