代码之家  ›  专栏  ›  技术社区  ›  vonaka

具有匿名互斥和结构的死锁

  •  -1
  • vonaka  · 技术社区  · 7 年前

    假设我有两个结构:

    type A struct {
        Mutex sync.Mutex
        i int
    }
    
    type B struct {
        A
        sync.Mutex
    }
    

    B A 我陷入了僵局:

    var b B
    b.Lock()
    b.Mutex.Lock()
    b.Mutex.Unlock()
    b.Unlock()
    

    A. ,例如,如果我命名它,则不会出现死锁 Mutexx 而不是 Mutex

    https://play.golang.org/p/UVi_WLWeGmi

    1 回复  |  直到 7 年前
        1
  •  5
  •   Community Mohan Dere    6 年前

    死锁的原因是因为代码将调用 Lock() 方法将同一互斥锁复制两次,这是一种阻塞操作。

    原因在于 Spec: Selectors:

    1. 为了一个价值 x 类型 T *T 哪里 T 不是指针或接口类型, x.f 表示当前位置的字段或方法 浅的 T f . 如果没有 one f 对于最浅的深度,选择器表达式是非法的。

    在里面 B sync.Mutex 值为 A ,及 还嵌入了一个 .

    当你写作时 B.Mutex 字段(非限定类型名用作字段名),以及 能够 也指 B.A.Mutex (因为 字段被嵌入到 B ),但根据上面引用的规则,它将表示 深度是多少 B.互斥 .

    同样地, b.Lock() B.Mutex.Lock() B.A.Mutex.Lock() . 但同样根据引用的规则,它将表示 浅的 B.Mutex.Lock() .

    b.Lock()
    b.Mutex.Lock()
    

    锁() 同样的方法 Mutex B.互斥 领域

    当你重命名 A.Mutex A.Mutexx

    b.Lock()
    b.Mutexx.Lock()
    

    第一 呼叫是指 B.Mutex.Lock() b.Mutexx.Lock() B.A.Mutexx.Lock() 调用,因此它们锁定2个不同的互斥锁;它们是独立的,因此第二个锁不会阻塞(其互斥锁尚未锁定)。