Goroutines 和 mutex
Goroutines and mutex
func (s *Server) start() {
s.Lock()
defer s.Unlock()
if !s.isClosed{
go s.processing()
}
go s.start()
}
func (s *Server) processing() {
s.Lock()
// do stuff
s.Unlock()
}
我有一个正在运行的 Golang 项目,其中有一段代码遵循上面显示的逻辑。
我不明白为什么这个逻辑会像我预料的那样运行死锁。
当 start
输入 G1 时,我们将调用 运行 的初始 goroutine。
start
(在 G1 中)锁定互斥锁并将解锁推迟到 start
returns.
start
在新的 goroutine (G2) 中调用 s.processing
start
在一个新的 goroutine (G3) 中调用自己
start
(G1) 解锁互斥和 returns.
None 这些调用中除了第 1 步的锁定是阻塞调用。 同时,在 G2 中,s.processing
等待 start
解锁互斥量(这会很快发生,因为 start
所做的只是启动几个 goroutine在解锁互斥量之前)。同时,在 G3 中,上述 4 个步骤再次执行(显然是无限循环)。
该逻辑没有任何意义会导致死锁。
func (s *Server) start() {
s.Lock()
defer s.Unlock()
if !s.isClosed{
go s.processing()
}
go s.start()
}
func (s *Server) processing() {
s.Lock()
// do stuff
s.Unlock()
}
我有一个正在运行的 Golang 项目,其中有一段代码遵循上面显示的逻辑。
我不明白为什么这个逻辑会像我预料的那样运行死锁。
当 start
输入 G1 时,我们将调用 运行 的初始 goroutine。
start
(在 G1 中)锁定互斥锁并将解锁推迟到start
returns.start
在新的 goroutine (G2) 中调用s.processing
start
在一个新的 goroutine (G3) 中调用自己start
(G1) 解锁互斥和 returns.
None 这些调用中除了第 1 步的锁定是阻塞调用。 同时,在 G2 中,s.processing
等待 start
解锁互斥量(这会很快发生,因为 start
所做的只是启动几个 goroutine在解锁互斥量之前)。同时,在 G3 中,上述 4 个步骤再次执行(显然是无限循环)。
该逻辑没有任何意义会导致死锁。