Неочевидная тупиковая ситуация - PullRequest
0 голосов
/ 25 мая 2018

Не могли бы вы объяснить, почему происходит этот тупик?

package main

import (
    "sync"
    "fmt"
    "runtime"
)

func main() {
    m := sync.RWMutex{}
    go func(){
        m.RLock()
        runtime.Gosched()
        m.RLock()
        m.RUnlock()
        m.RUnlock()
    }()

    runtime.Gosched()
    m.Lock()
    m.Unlock()

    fmt.Println("works")
}

Для меня не очевидно, почему этот тупик всегда в основном случается. Может ли это быть причудой планировщика?

1 Ответ

0 голосов
/ 25 мая 2018

Из документа RWMutex:

Если в программе есть RWMutex для чтения, а другая программа может вызвать Lock, никакая программа не должна ожидать получения блокировки чтения до начальнойблокировка чтения снята .В частности, это запрещает рекурсивную блокировку чтения.Это сделано для того, чтобы блокировка в конечном итоге стала доступной;заблокированный вызов блокировки не позволяет новым читателям получить блокировку.

Что происходит в вашем коде при возникновении взаимоблокировки:

  1. first RLock ()
  2. Lock () // этот вызов ожидает, пока не будет выпущен первый Rlock (), и блокирует вызовы для будущих Rlocks ()
  3. Rlock () // этот вызов ожидает, пока не будет освобожден Lock ()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...