-3
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 项目,其中有一段代码遵循上面显示的逻辑。

我不明白为什么这种逻辑会像我预期的那样会出现死锁。

4

1 回答 1

0

start我们将调用进入 G1时正在运行的初始 goroutine 。

  1. start(在 G1 中)锁定互斥锁并将解锁推迟到start返回。
  2. start调用s.processing一个新的 goroutine (G2)
  3. start在一个新的 goroutine (G3) 中调用自己
  4. start(G1) 解锁互斥锁并返回。

除了第 1 步的锁之外,这些调用都不是阻塞调用。同时,在 G2 中,s.processing等待start解锁互斥锁(这将很快发生,因为start在解锁互斥锁之前只需启动几个 goroutine)。同时,在 G3 中,上述 4 个步骤将重新执行(显然是无限循环)。

这种逻辑没有任何意义会导致死锁。

于 2018-06-19T19:47:59.260 回答