我正在使用一个库,它在事件发生时使用多线程来调用成员函数。库中的每个“处理程序”都有一个可以调用函数MyClass::Process(const Signal& signal)
的线程。 MyClass引用了一个名为Catalog
的{{1}}类。
cat
内部我有以下代码:
Process
从图书馆的文件:
Handler的单个实例的边界不可能有两个 用户回调要同时调用。但是,不同 不同渠道的处理程序实例不与每个渠道链接 另外,因此来自不同Handler实例的调用可以 并行发生。
目录中有成员Stats stats;//simple container struct to hold values
std:string id(signal.signalId());
//set values of stats here based on the values in signal
cat->onSignalUpdate(id, stats);
std::map<std::string, Stats> signal_map
Catalog::onSignalUpdate(const std::string& id, const Stats& stats)
这在很多时候都适用,其中正确的ID被映射到适当的Stats结构。偶尔我会得到不正确的匹配,其中Handler A的ID被分配给属于Handler B的结构。在我看来,该函数是并行调用的。我的印象是,在线程中,对函数的调用虽然并行完成,但却是重复的。是不是这种情况,或者是否存在通过线程中的引用传递值的问题?
答案 0 :(得分:2)
如果没有针对同时修改std::map
的多个线程的某种形式的保护,您无法从多个线程更新map
。你需要一个互斥或类似的东西。在partciular中,如果id
是“new”,那么地图中的基础数据结构(通常是“RB-tree”)将被更改。这绝不能从多个线程完成。在修改树时,您也无法访问树“读取”,因为树中的条目可能是“半更新”(例如,下一个元素指向未正确填充的元素或一些这样的)。