Механизм pthread_join удобно использовать, если он делает именно то, что вы хотите. Он не делает ничего, что вы не можете сделать сами, и где это не совсем то, что вы хотите, кодируйте именно то, что вы хотите.
Нет реальной причины, по которой вы должны заботиться о том, завершился поток или нет. Вас волнует, завершена ли работа, которую выполнял поток. Чтобы сказать это, попросите поток сделать что-то, чтобы показать, что он работает. То, как вы это сделаете, зависит от того, что идеально подходит для вашей конкретной задачи, и в значительной степени зависит от того, что делают потоки.
Начните с изменения вашего мышления. Застревает не нить, а то, чем занимался нить.