You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++多线程归并排序程序处理大规模数组时中途终止问题求助

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

内容的提问来源于stack exchange,提问作者TDTejani Sherlock

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 21:27:03