各位大佬,下面的 Go 代码中,当主 Goroutine 执行到 c.Wait() 的时候,第 28 行的 c.L.Lock() 肯定执行了,那么当执行到第 17 行的 c.L.Lock(),为什么程序不会一直阻塞呢?
package main
import (
"fmt"
"sync"
"time"
)
// a goroutine that is waiting for a signal, and a goroutine that is sending signals.
// Say we have a queue of fixed length 2, and 10 items we want to push onto the queue
func main() {
c := sync.NewCond(&sync.Mutex{})
queue := make([]interface{}, 0, 10)
removeFromQueue := func(delay time.Duration) {
time.Sleep(delay)
c.L.Lock() // 这是第 17 行,执行到这里为什么不是一直阻塞等待锁?
queue = queue[1:]
fmt.Println("Removed from queue")
c.L.Unlock()
c.Signal() // let a goroutine waiting on the condition know that something has ocurred
}
for i := 0; i < 10; i++ {
c.L.Lock() // 这是 28 行,critical section
// When the queue is equal to two the main goroutine is suspend
// until a signal on the condition has been sent
length := len(queue)
fmt.Println(length)
for len(queue) == 2 {
fmt.Println("wait signal")
c.Wait() // 这是 36 行,等待 signal ,但是 removeFromQueue 为什么不会一直等待锁呢?
}
fmt.Println("Adding to queue")
queue = append(queue, struct{}{})
go removeFromQueue(10 * time.Second)
c.L.Unlock()
}
}
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.