Более серьезная проблема с вашим кодом и, вероятно, причина тупиков, заключается в использовании вами режима асинхронной отмены (я пропустил это раньше). Только 3 функции в POSIX безопасны для асинхронной отмены:
- pthread_cancel ()
- pthread_setcancelstate ()
- pthread_setcanceltype ()
Источник: http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_09_05_04
Вы, конечно, не можете блокировать и разблокировать мьютексы, когда включен режим асинхронной отмены.
Для использования асинхронной отмены необходимо сделать однуиз следующих вещей:
- Используйте его только с чисто вычислительным кодом, например, выполняйте сложную математику без каких-либо обращений к библиотеке, только арифметические операции или
- Постоянно отключайте его ивозвращайтесь к каждому библиотечному вызову, который вы делаете.
Редактировать: Основываясь на комментариях, я думаю, что вы неправильно понимаете, что означает асинхронный тип отмены.Это не имеет ничего общего с тем, как работают обработчики очистки.Это просто вопрос того, в какой момент поток может перехватить запрос на отмену и начать действовать в соответствии с ним.
Когда цель находится в режиме отложенного отмены, вызов pthread_cancel
для нее не обязательно сделает что-либо сразу, если толькоон уже заблокирован в функции (например, read
или select
), которая является точкой отмены.Вместо этого он просто установит флаг, и в следующий раз, когда будет вызвана функция, которая является точкой отмены, поток вместо этого заблокирует любые дальнейшие попытки отмены, запустит обработчики очистки отмены в обратном порядке, в котором они были выдвинуты, и выйдет со специальнымсостояние, указывающее, что поток был отменен.
Когда цель находится в режиме асинхронной отмены, вызов pthread_cancel
на нем немедленно прервет поток (возможно, между любой парой соседних инструкций машинного кода).Если вы не понимаете, почему это потенциально опасно, подумайте об этом на секунду.Любая функция, имеющая внутреннее состояние (статические / глобальные переменные, файловые дескрипторы или другие ресурсы, выделяемые / освобождаемые и т. Д.) Может находиться в несогласованном состоянии в момент прерывания: переменная частично изменена, получена блокировка на полпути, получен ресурсно без записи о том, что он был получен или освобожден, но без записи о том, что он был освобожден и т. д.
В точке асинхронного прерывания дальнейшие запросы отмены блокируются, поэтому опасности вызова нетлюбую функцию, которая вам нравится из ваших обработчиков очистки.Когда обработчики очистки завершают работу, поток, конечно, перестает существовать.
Еще один потенциальный источник путаницы: обработчики очистки не работают параллельно с отменой потока.Когда отменяется действие, отмененный поток прекращает выполнение нормального потока кода и вместо этого запускает обработчики очистки, а затем завершает работу.