Вопрос:

Обнаружение одной и той же программы, вызывающей sync.Mutex.Lock () дважды подряд

go locking mutex reentrancy

8 просмотра

1 ответ

22118 Репутация автора

Этот код никогда не будет работать:

func TestDoubleLockPanics(t *testing.T) {
    var mu sync.Mutex
    mu.Lock()
    mu.Lock()
}

Однако когда я запускаю этот тест, паники нет. Детектор гонки не распечатывает данные гонки. go vetне жалуется, журнала нет, просто блокируется навсегда.

(Фактический реальный код, который мне небезразличен, очевидно, не так прост - я просто свел его к сути.)

Есть ли способ заставить Go сказать мне громко, когда поток, который держит блокировку, пытается повторно получить ту же блокировку?

Автор: Kevin Burke Источник Размещён: 11.08.2019 06:41

Ответы (1)


0 плюса

219160 Репутация автора

sync.MutexОбъекты Go не отслеживают, какая программа заблокировала их. Или, иначе говоря, есть не запирающая нить: есть только блокировка данных.

Более того, как Unlockговорится в приведенном выше комментарии , вы можете разблокировать их из какой-либо другой программы, кроме той, которая их заблокировала. Следовательно, на самом деле имеет смысл звонить Lockдважды. Вот пример скелета:

func f() {
    mu.Lock()
    ... if this is not just an example, some code goes here ...
    // now wait for g() to call mu.Unlock()
    mu.Lock()
    fmt.Println("we got here, so g() must have done an unlock")
    mu.Unlock()
}

func g() {
    ... some code probably goes here too ...
    mu.Unlock() // allow f() to proceed
    ... more code, perhaps ...
}

В этом случае мы бы не хотели паники во fвтором Lockзвонке.

Вы можете создать свои собственные рекурсивные блокировки или другие методы, но поскольку внутренний идентификатор каждой программы скрыт, это довольно сложно . В комментариях к этому ответу на рекурсивную блокировку в Go есть ссылка на реализацию , но я никогда не использовал ее и даже не присматривался к ней.

Автор: torek Размещён: 11.08.2019 07:56
Вопросы из категории :
32x32