Изменение комментария Spong в качестве ответа: ваш класс locker
НЕ ДОЛЖЕН копировать значение pthread_mutex_t
по значению. Вместо этого вы должны использовать ссылку или указатель, например ::100100
class locker
{
public:
locker(pthread_mutex_t& lockee): target(lockee)
{
pthread_mutex_lock(&target);
}
~locker()
{
pthread_mutex_unlock(&target);
}
private:
pthread_mutex_t& target; // <-- this is a reference
};
Причина этого в том, что все типы данных pthreads должны рассматриваться как непрозрачные типы - вы не знаете, что в них, и не должны их копировать. Библиотека делает такие вещи, как просмотр определенного адреса памяти, чтобы определить, удерживается ли блокировка, поэтому, если есть две копии переменной, указывающей, удерживается ли блокировка, могут происходить странные вещи, например, появление нескольких потоков, которые успешно блокируются тот же мьютекс.
Я проверил твой код, и он тоже для меня заблокирован. Затем я пропустил его через Valgrind , и хотя в этом случае он не зашел в тупик (из-за разного времени или, возможно, Valgrind имитирует только один поток за раз), Valgrind сообщил о многочисленных ошибках. После исправления locker
для использования ссылки вместо этого он работал без блокировки и не генерировал никаких ошибок в Valgrind.
См. Также Отладка с помощью pthreads .