C++递归创建多线程如何正确设计 保证所有线程执行完毕后再执行后续操作
存在的问题
你当前的实现本身存在多个未定义行为:
std::vector不是线程安全容器,多个子线程并发执行push_back会直接导致容器结构损坏- 共享变量
i没有任何同步保护,多线程并发修改会产生数据竞争,计数逻辑完全不可控 - 主函数首次调用
DummyFunction返回后就直接遍历线程容器,此时子线程可能还在往容器中新增线程,遍历过程中容器扩容会直接触发崩溃,就算不崩溃也会漏掉后续新增的线程,无法完成全部join。
正确设计方案
这种递归拉取依赖的场景,推荐用原子任务计数+条件变量的方案实现全局等待,不需要存储所有线程对象,逻辑更简单也更安全:
实现思路
- 用原子整型统计当前正在运行的任务总数,每个任务启动时计数加1,任务执行结束前计数减1
- 用条件变量在主线程阻塞等待,直到任务计数降到0,代表所有递归生成的任务全部执行完成
- 所有跨线程共享的可变数据操作必须加锁保护,或者避免跨线程共享
- 也可以搭配线程池复用线程,避免递归过程中反复创建销毁线程的额外开销,还能控制最大并发数避免系统资源耗尽
修复后的示例代码
#include <thread> #include <mutex> #include <condition_variable> #include <atomic> #include <iostream> std::atomic<int> task_count = 0; std::mutex mtx; std::condition_variable cv; int i = 0; const int MAX_LIMIT = 10; void DummyFunction() { // 本任务执行逻辑 { std::lock_guard<std::mutex> lock(mtx); ++i; std::cout << "当前i值:" << i << ",执行线程id:" << std::this_thread::get_id() << std::endl; } // 需要生成子任务的场景 if (i < MAX_LIMIT) { // 每生成一个子任务,计数加1 task_count.fetch_add(1); std::thread t([](){ DummyFunction(); // 子任务执行结束,计数减1 if (task_count.fetch_sub(1) == 1) { // 计数降到0时通知主线程 cv.notify_one(); } }); t.detach(); // 不需要持有线程对象,直接detach交给系统调度 } } int main() { // 初始任务计数加1 task_count.fetch_add(1); DummyFunction(); // 初始任务执行结束,计数减1 if (task_count.fetch_sub(1) != 0) { // 还有子任务在运行,阻塞等待 std::unique_lock<std::mutex> lock(mtx); cv.wait(lock, [](){ return task_count == 0; }); } std::cout << "所有任务执行完成,最终i值:" << i << std::endl; return 0; }
常见问题解答
- 递归逻辑中可以使用多线程,只要做好跨线程数据的同步保护,避免数据竞争即可
- 如果依赖拉取的量级较大,更推荐将每个节点的拉取解析逻辑封装成任务提交到固定大小的线程池执行,相比递归中动态创建线程的方案,资源开销更低,并发控制更灵活
内容的提问来源于stack exchange,提问作者loyd.f
相关产品推荐
相关产品推荐

