POSIX позволяет мьютексам быть рекурсивными. Это означает, что один и тот же поток может блокировать один и тот же мьютекс дважды и не блокируется. Конечно, он также должен разблокировать его дважды, иначе никакой другой поток не сможет получить мьютекс. Не все системы, поддерживающие pthreads, также поддерживают рекурсивные мьютексы, но если они хотят соответствовать POSIX, они должны .
Другие API (более высокоуровневые API) также обычно предлагают мьютексы, часто называемые Locks. Некоторые системы / языки (например, Cocoa Objective-C) предлагают как рекурсивные, так и нерекурсивные мьютексы. Некоторые языки также предлагают только один или другой. Например. в Java мьютексы всегда рекурсивны (один и тот же поток может дважды «синхронизироваться» с одним и тем же объектом). В зависимости от того, какую другую функциональность потоков они предлагают, отсутствие рекурсивных мьютексов может быть проблемой, поскольку их можно легко написать самостоятельно (я уже сам реализовал рекурсивные мьютексы на основе более простых операций мьютекс / условие).
Что я не очень понимаю: для чего нужны нерекурсивные мьютексы? Зачем мне нужен тупик потока, если он дважды блокирует один и тот же мьютекс? Даже языки высокого уровня, которые могут этого избежать (например, тестирование, если это приведет к взаимоблокировке, и создание исключения, если это произойдет), обычно этого не делают. Вместо этого они позволят заблокировать поток.
Это только для случаев, когда я случайно блокирую его дважды и разблокирую только один раз, а в случае рекурсивного мьютекса будет сложнее найти проблему, поэтому вместо этого я немедленно захожу в тупик, чтобы увидеть, где неправильная блокировка появляется? Но не могу ли я сделать то же самое с возвращением счетчика блокировки при разблокировке и в ситуации, когда я уверен, что снял последнюю блокировку, а счетчик не равен нулю, я могу выдать исключение или зарегистрировать проблему? Или есть какой-то другой, более полезный вариант использования нерекурсивных мьютексов, который я не вижу? Или это просто производительность, так как нерекурсивный мьютекс может быть немного быстрее, чем рекурсивный? Тем не менее, я проверил это, и разница действительно не так велика.