Вы можете решить эту проблему с помощью условных переменных. Вместо того, чтобы поток 4 ожидал только условия, заданного потоком 2, он должен ожидать условия, которое устанавливается только после того, как все потока 1, потока 2 и потока 3 выполнили свою задачу:
pthread_mutex_lock(&thread4_lock);
while (!thread1_flag || !thread2_flag || !thread3_flag)
pthread_cond_wait(&thread4_cond, &thread4_lock);
pthread_mutex_unlock(&thread4_lock);
/* Thread 4 can continue */
Когда поток 1 выполнил свою задачу, он устанавливает свою часть условия:
pthread_mutex_lock(&thread4_lock);
thread1_flag = 1;
pthread_cond_signal(&thread4_cond);
pthread_mutex_unlock(&thread4_lock);
... и аналогично для потоков 2 и 3. Поток 4 продолжится только после установки всех флагов.