Звучит так, как будто вы страдаете от тупика. Ваши потоки когда-либо содержат более одного мьютекса за раз? (например, pthread_mutex_lock (& mutex1); pthread_mutex_lock (& mutex2);) Если это так, всегда ли они блокируют одновременно удерживаемые мьютексы в одном и том же порядке? Если они этого не сделают, это будет проблемой.
Если поток T1 выполняет вышеупомянутую последовательность блокировки, но поток T2 блокирует mutex2, а затем mutex1 (при этом все еще удерживая mutex2), то это все, что необходимо для того, чтобы вызвать случайный тупик ... что означало бы, что T1 удерживает mutex1 и ожидание доступности mutex2, в то время как T2 одновременно удерживает mutex2 и ожидает mutex2, и оба застряли навсегда. Или, если вам действительно не повезло, тупик может включать цикл из 3 или более мьютексов.
Обратите внимание, что даже если ваш собственный код явно не блокирует второй мьютекс, возможно, что какая-то библиотека или вызов функции, к которой обращается ваш код, блокирует свой собственный мьютекс внутри. Этого в сочетании с вашим собственным мьютексом может быть достаточно и для тупика.
Лучше всего было бы запустить вашу программу под отладчиком (например, gdb), а затем, когда он заблокировался, взломать отладчик и распечатать текущую трассировку стека каждого потока (с помощью команды "где") чтобы увидеть, где он заблокирован.