使用std::async多核运行时无法保存值的问题排查
问题根源
你创建异步任务后,没有等待所有任务执行完毕就进入后续逻辑(比如构造SudokuSolver)。虽然addDigitToPredictions里能打印出正确结果,但那是异步线程的输出,主线程已经继续往下走,此时sudoku.m_ScannedDigits的赋值操作可能还没全部完成,导致后续代码看到的还是初始的0值。
修复方案
在所有异步任务创建完成后,遍历存储std::future的容器,调用每个future的get()方法,强制主线程等待所有异步任务执行完毕,再继续后续代码。同时建议每次调用classifySudoku前清空m_Futures,避免累积旧任务占用资源。
修改后的代码:
void DigitClassifier::classifySudoku(cv::Mat* (&digits)[81], Sudoku &sudoku) { // 清空旧的future,避免累积 m_Futures.clear(); for(int row = 0; row < 9; row++) { for(int col = 0; col < 9; col++) { m_Futures.push_back(std::async(std::launch::async, &DigitClassifier::addDigitToPredictions, this, digits[row + col * 9], &sudoku.m_ScannedDigits[row][col])); } } // 等待所有异步任务完成,确保赋值操作全部执行完毕 for(auto& future : m_Futures) { future.get(); } // 此时所有数字分类结果已写入数组,再执行后续逻辑 SudokuSolver s; }
额外说明
std::future::get()会阻塞当前线程,直到对应的异步任务执行完成,这能保证所有对sudoku.m_ScannedDigits的赋值操作都完成后,主线程才会继续处理。- 确保
sudoku对象的生命周期覆盖所有异步任务的执行时间(这里sudoku是引用传递,只要调用classifySudoku的地方对象未销毁,就不会有问题)。
内容的提问来源于stack exchange,提问作者david-palm
相关产品推荐
相关产品推荐

