首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

MFC 多線程使用 STL map/vector 導致崩潰:非線程安全容器需加鎖

     編輯:程式設計綜合問答

錯誤現象

工作線程並發操作 `std::map>`,報錯:`map/set iterator not decrementable`、訪問違例、堆損壞。

根因

STL 容器非線程安全:多線程同時修改(`operator[]`、`push_back`、rehash、迭代器失效)導致內部結構破壞。

解決方案

方案一:關鍵區鎖(最簡單)

CCriticalSection csMap; // MFC 互斥量

// 線程函數
csMap.Lock();
auto& vec = map[key];   // operator[] 可能插入
vec.push_back(value);
csMap.Unlock();

方案二:無鎖併發容器

  • Intel TBB `concurrent_hash_map`、`concurrent_vector`。
  • C++17 `std::shared_mutex` + 讀寫分離(讀多寫少場景)。

方案三:線程局部存儲 + 歸併

// 每線程私有 map
thread_local std::map> localMap;
// 工作結束後主線程歸併
for (auto& [k, v] : localMap) globalMap[k].insert(end, v.begin(), v.end());

MFC 具體修正

將 `CDotPlots::m_csCritical` 保護範圍擴大到**整個 map/vector 操作序列**,而非僅保護單行:

csMap.Lock();
VALUE& mapCol = pThreadInfo->pDotPlot->m_mapParticles[x];
IDS& vIDS = mapCol[y];
vIDS.push_back(i);
csMap.Unlock();

避坑

  • 鎖粒度過大影響並發度,按 Key 分段鎖(分段鎖/條帶鎖)可提升吞吐。
  • 迭代器遍歷期間**嚴禁**其他線程修改容器,需拷貝快照或持有讀鎖。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved