C++多线程归并排序程序处理大规模数组时中途终止问题求助
程序崩溃原因分析
- 并发数据竞争(核心问题)
代码中worker线程负责修改排序vectornum,主线程在sortChecker中反复读取同一个num,两个线程未加任何同步机制同时读写同一块内存,属于C++标准定义的未定义行为。小数据量下排序执行快、访问冲突概率低所以能正常运行,大数据量下排序时间变长,并发读写冲突概率大幅升高,直接触发程序崩溃。
同时共享的超时标记isTimeOut是普通布尔类型,多线程下读写无原子性保证,编译器可能优化掉worker线程对该变量的读取逻辑,导致主线程设置的超时标记无法被worker线程感知。 - 高频大内存拷贝消耗过高
sortChecker函数采用值传递参数,每次调用都会完整拷贝一份待检查的vector,当测试规模达到10万级时,单次拷贝就需要占用约400KB内存,而主线程死循环无间隔调用该函数,会在短时间内耗尽CPU和内存资源,触发系统强制结束进程。 - 主线程空转占用全部CPU资源
轮询检查逻辑未加任何休眠逻辑,主线程会占满一整个CPU核心不停执行检查逻辑,既会抢占worker排序线程的CPU资源,也会导致系统负载过高触发崩溃。
修复方案
- 替换超时标记类型:将
bool isTimeOut改为std::atomic<bool> isTimeOut,保证多线程下读写的原子性和可见性,需要额外包含<atomic>头文件。 - 修改参数传递方式:将
sortChecker的参数改为常量引用,避免不必要的全量数组拷贝:
bool sortChecker(const vector<int>& v) { for (int i = 0; i < (int)v.size() - 1; ++i) { if (v[i] > v[i + 1]) return false; } return true; }
- 轮询逻辑增加休眠间隔:在检查循环中加入100ms的休眠,降低CPU占用:
while ( ( ( timer.durationCounter() / 1000000 ) < 5) && (!isSorted ) ) { this_thread::sleep_for(milliseconds(100)); isSorted = sortChecker(num); }
- (可选)加锁保护共享资源:如果需要保证排序过程中读取数组的正确性,可添加
std::mutex,在worker线程修改数组、主线程读取数组时都先加锁再操作,避免数据竞争。
内容的提问来源于stack exchange,提问作者TDTejani Sherlock
相关产品推荐
相关产品推荐

