如何初始化Semaphore让父线程等待三个子线程全部执行完成?
信号量初始化与线程同步问题解答
首先明确核心需求:父线程必须在3个子线程全部执行完sem_post()后才能继续执行(结束)。
你的思路问题点
你想初始化sem_init(&s, 1, -2)是非法的:POSIX标准明确规定,sem_init()的第三个参数(信号量初始值)必须是非负整数,设置负数会触发未定义行为,根本不能这么用。
退一步说,即便允许初始值为负,你的担心也成立:sem_post()的逻辑是,只要有线程阻塞在sem_wait()上,不管信号量增量后的值是否仍小于0,都会唤醒一个阻塞线程。所以第一个子线程执行sem_post()时,父线程就会被唤醒,此时另外两个子线程可能还没完成,完全不符合需求。
正确的实现方式
1. 信号量初始化
sem_init(&s, 0, 0):
- 第二个参数
0:表示信号量仅在当前进程的线程间共享(因为你是同一进程内创建子线程,不需要进程间共享); - 第三个参数
0:信号量初始值为0。
2. 父线程代码修改
父线程需要调用三次sem_wait(&s),对应三个子线程的sem_post():
sem_t s; int main(int argc ,char *argv[]) { thread_t p1, p2, p3; sem_init(&s, 0, 0); thread_create(&p1, child); thread_create(&p2, child); thread_create(&p3, child); // 等待三个子线程全部完成 sem_wait(&s); sem_wait(&s); sem_wait(&s); }
逻辑说明
- 初始信号量值为0,父线程调用第一次
sem_wait()时会阻塞; - 每个子线程完成任务后调用
sem_post(),信号量值加1,同时唤醒一个阻塞的sem_wait(); - 三次
sem_post()执行完毕后,父线程的三次sem_wait()全部完成,才能继续执行后续逻辑(结束进程),保证了三个子线程都已完成。
补充说明
如果一定要让父线程只调用一次sem_wait(),单纯靠信号量无法实现,需要结合计数器+条件变量等其他同步机制,但题目限定用信号量的话,三次sem_wait()是最直接合规的方案。
内容的提问来源于stack exchange,提问作者Lorenzo
相关产品推荐
相关产品推荐

