При снятии блокировки чтения/записи Helgrind сообщил о следующей ошибке:
pthread_rwlock_destroy of a locked mutex
Если оставить в стороне тот факт, что я уничтожаю блокировку, а не мьютекс (хотя реализация библиотеки может полагаться на мьютексы), ошибка, вероятно, верна, тем более что последующая попытка снять блокировку помечается Helgrind как высвобождающая недействительную блокировку. замок.
Я понимаю, что разрушение блокировки, удерживаемой другим потоком, вероятно, является ошибкой. (Блокировки обычно уничтожаются вместе с ресурсом, который они защищают, и если блокировка удерживается, это означает, что ресурс все еще используется и не должен быть уничтожен).
Теперь мои вопросы:
Is it an error to destroy a lock that is still being held by the current thread?
Да это так. POSIX говорит:
Results are undefined if
pthread_rwlock_destroy()
is called when any thread holdsrwlock
.
Это понятно — «любой поток» включает в себя текущий поток.
Рассуждение будет примерно таким: либо другой поток может состязаться за блокировку с pthread_rwlock_destroy()
текущего потока, либо он не может. Если будет могу, то программа уже ошибочна, т.к. попытка блокировки неинициализированной блокировки не определена; если это невозможно, то текущему потоку достаточно сначала разблокировать блокировку, а затем разрушить ее.
If so, how can I prevent other threads from acquiring the lock and messing with the resource when I am about to destroy both?
Рассуждения выше намекают на ответ на это — чтобы уничтожить объект, включая блокировку внутри него, вы должны первый сделать его недоступным для любого другого потока. Вы бы сделали это, удалив все ссылки на него из других структур данных, что, вероятно, включает в себя снятие и снятие других блокировок, но как только вы изолируете сам объект, вы можете безопасно разблокировать его, потому что ваш поток должен тогда удерживать единственную оставшуюся ссылку.