Рекурсивный или проверочный мьютекс? - PullRequest
2 голосов
/ 19 апреля 2011

До недавнего времени я рассматривал мьютексы проверки ошибок главным образом как инструмент отладки с небольшим значением в правильном коде, но потом я понял, что у них есть свойство заменять рекурсивные мьютексы, как в:

void foo()
{
    int ok_to_unlock = !pthread_mutex_lock(m);
    /* do something */
    if (ok_to_unlock) pthread_mutex_unlock(m);
}

Обратите внимание, что pthread_mutex_lock возвращает 0 в случае успеха и EDEADLK, если вызывающая сторона уже удерживает блокировку. Преимущество такого использования заключается в том, что вам не нужно беспокоиться о превышении произвольного предела рекурсивной блокировки; «Счетчик блокировок» неявно присутствует в кадре вызова. В принципе, эта идиома может также работать немного лучше, поскольку вызов функции pthread_mutex_unlock никогда не выполняется, когда вызывающий поток уже удерживал блокировку.

Мой вопрос, в основном, касается стиля: не мешает ли использование мьютексов для проверки ошибок, подобных этому, ясность кода? Есть ли другие причины, по которым вы бы не хотели их использовать?

Ответы [ 3 ]

2 голосов
/ 08 мая 2011

Обратите внимание, что pthread_mutex_lock возвращает 0 в случае успеха и EDEADLK, если вызывающий уже удерживает блокировку.

Ваш опубликованный код не является полностью надежным, поскольку EDEADLK является , а не единственной возможной ошибкой, которая может быть возвращена. Существует также EINVAL, если мьютекс не был правильно инициализирован.

На слегка касательной ноте у Дэвида Бутенхофа есть интересных предупреждений об использовании рекурсивных мьютексов.

2 голосов
/ 19 апреля 2011

Это субъективно, но я чувствую, что это делает код менее понятным.

1 голос
/ 19 апреля 2011

Я думаю, что любой прирост производительности, который вы могли бы себе представить, был бы подавлен затратами на использование проверочного мьютекса в первую очередь. Тем не менее, даже эти расходы, вероятно, будут небольшими, и я не вижу причин, чтобы не использовать эту идиому. Мой единственный комментарий - использовать имя переменной, например locked, а не ok_to_unlock.

...