Потоки, пытающиеся получить pthread_mutex_lock (& ​​mutex) Что произойдет, если они не получат блокировку? - PullRequest
6 голосов
/ 11 марта 2011

C Программирование:

Что происходит, когда поток пытается получить блокировку мьютекса и не может ее получить?

идет ли спать?

Поток будет пробужден, когда pthread_mutex_unlock (& ​​mutex); называется?

Тогда попробуйте снова получить блокировку?

Ответы [ 4 ]

8 голосов
/ 11 марта 2011

со страницы руководства :

Функция pthread_mutex_lock() блокирует мьютекс . Если мьютекс уже заблокирован, вызывающий поток будет блокироваться, пока мьютекс не станет доступным.

Так что да - ваш поток заблокирован до тех пор, пока блокировка не будет доступна и он не сможет ее получить.

3 голосов
/ 11 марта 2011

Обычно pthread_mutex_lock не может вернуться, пока не получит блокировку, даже если это означает, что он никогда не возвращается (тупик).Однако есть несколько заметных исключений:

  • Для рекурсивных мьютексов он может вернуть EAGAIN, если будет превышен максимальный счетчик ссылок.
  • Для мьютексов с проверкой ошибок он можетreturn EDEADLK если поток пытается заблокировать мьютекс, он уже удерживает блокировку.
  • Для надежных мьютексов он может вернуть EOWNERDEAD, если другой процесс умер, удерживая (общий) мьютекс.В этом случае, несмотря на получение сообщения об ошибке, вызывающая сторона удерживает блокировку мьютекса и может снова отметить состояние, защищенное мьютексом, путем вызова pthread_mutex_consistent.
  • Для надежных мьютексов, владелец которых умер, и для которых новый владелецвызванный pthread_mutex_unlock без вызова pthread_mutex_consistent первым, он вернет ENOTRECOVERABLE.

Могут быть несколько случаев, которые я пропустил.Обратите внимание, что ни один из них не применим к обычным мьютексам (тип PTHREAD_MUTEX_NORMAL) без набора надежных атрибутов, поэтому, если вы используете только нормальные мьютексы, вы можете разумно предположить, что вызов никогда не завершится без успеха.

3 голосов
/ 11 марта 2011

Да, это блокирующий вызов, и он будет блокироваться, пока не получит блокировку.

Неблокирующая версия - pthread_mutex_trylock(pthread_mutex_t *mutex) и вернет EBUSY, если у кого-то еще есть блокировка, или 0 если он получил замок.(Или какая-то другая ошибка, конечно)

0 голосов
/ 11 марта 2011

Из стандарта POSIX :

Если мьютекс уже заблокирован, вызывающий поток блокируется, пока мьютекс не станет доступным.

(...)

Если в объекте мьютекса имеются ссылки на потоки, на которые ссылается mutex при вызове pthread_mutex_unlock(), в результате чего мьютекс становится доступным, политика планирования должна определить, какой поток должен получить мьютекс.*

Там, где необходимо выражение «result», потому что

(В случае мьютексов PTHREAD_MUTEX_RECURSIVE мьютекс должен стать доступным, когда счетчик достигнет нуля и вызывающий потокбольше нет замков на этом мьютексе.)

...