pthread_rwlock_destroy заблокированного мьютекса - PullRequest
1 голос
/ 10 апреля 2019

При уничтожении блокировки чтения / записи Хелгринд сообщал о следующей ошибке:

pthread_rwlock_destroy заблокированного мьютекса

Если оставить в стороне тот факт, что я уничтожаю блокировку, а не мьютекс (хотя реализация библиотеки может опираться на мьютексы), ошибка, вероятно, является точной, особенно потому, что последующая попытка снять блокировку помечена Хелгриндом как снятие недействительной блокировки.

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

Теперь мои вопросы:

  • Ошибка уничтожить блокировку, которая все еще удерживается потоком current ?
  • Если это так, что за этим стоит?
  • Если это так, как я могу предотвратить блокировку других потоков и возиться с ресурсом, когда я собираюсь уничтожить оба?

1 Ответ

3 голосов
/ 11 апреля 2019

Ошибка уничтожить блокировку, которая все еще удерживается текущим потоком?

Да, это так.POSIX говорит:

Результаты не определены, если pthread_rwlock_destroy() вызывается, когда какой-либо поток содержит rwlock.

Это ясно - «любой поток» включает текущий поток.

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

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

Приведенные выше рассуждения намекают на ответ на этот вопрос - чтобы уничтожить объект, включая замок внутри него, вы должны сначала сделать его недоступным для любогодругая нить.Вы могли бы сделать это, удалив все ссылки на него из других структур данных, что, вероятно, включает в себя снятие и снятие других блокировок, но как только вы изолировали сам объект, вы можете безопасно разблокировать его, потому что ваш поток должен содержать единственную оставшуюся ссылку.

...