C语言中多线程等待同一线程结束的阻塞问题排查
问题分析与解决方案
你的问题根源在于POSIX标准未定义多个线程同时调用pthread_join等待同一线程的行为——虽然部分系统实现可能允许这种操作,但这不属于标准保证的可靠行为,因此会出现仅单个线程完成、其余线程无限阻塞的异常情况。
正确实现方案:使用条件变量同步
改用条件变量+互斥锁的组合,让1、2、3号线程等待4号线程的结束信号,这是符合POSIX标准的可靠同步方式:
#include<stdio.h> #include<pthread.h> #include<stdlib.h> #include<unistd.h> pthread_t id[4]; pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t cond = PTHREAD_COND_INITIALIZER; // 标记4号线程是否完成 int thread4_finished = 0; void *func1(void *arg) { int thread_num = (int)arg; printf("I am the %dth thread\n", thread_num); // 等待4号线程结束 pthread_mutex_lock(&mutex); while (!thread4_finished) { pthread_cond_wait(&cond, &mutex); } pthread_mutex_unlock(&mutex); printf("End of %dth thread\n", thread_num); pthread_exit(NULL); } void *func2(void *arg) { printf("I am the 4th thread\n"); sleep(5); printf("End of 4th thread\n"); // 标记完成并唤醒所有等待线程 pthread_mutex_lock(&mutex); thread4_finished = 1; pthread_cond_broadcast(&cond); pthread_mutex_unlock(&mutex); pthread_exit(NULL); } int main() { printf("Start of main thread\n"); pthread_mutex_init(&mutex, NULL); pthread_cond_init(&cond, NULL); pthread_create(&id[3], NULL, func2, NULL); for(int i=0; i<3; i++) { pthread_create(&id[i], NULL, func1, (void *)i); } // 等待1、2、3号线程结束 for(int i=0; i<3; i++) { pthread_join(id[i], NULL); } pthread_mutex_destroy(&mutex); pthread_cond_destroy(&cond); printf("End of main\n"); return 0; }
方案说明
- 互斥锁:保护
thread4_finished变量的线程安全访问,避免多个线程同时修改或读取导致的竞态条件。 - 条件变量:
pthread_cond_wait让1、2、3号线程进入休眠,直到4号线程发送唤醒信号,期间会自动释放互斥锁,避免死锁。 - 广播唤醒:
pthread_cond_broadcast会唤醒所有等待该条件变量的线程,确保1、2、3号线程都能在4号线程结束后继续执行。
这样修改后,程序会稳定执行,所有线程都会在4号线程结束后正常终止,主线程也能顺利完成等待逻辑。
内容的提问来源于stack exchange,提问作者Abdellah Badaoui
相关产品推荐
相关产品推荐

