通过引用使用参数进行 C++ 多线程函数调用



我正在使用一个库,该库使用多线程在事件发生时调用成员函数。库中的每个"处理程序"都有一个可以调用函数MyClass::Process(const Signal& signal)的线程。MyClass 引用了一个名为 catCatalog类。

Process里面,我有以下代码:

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)内部

std::map<std::string, Stats>::iterator it(signal_map.find(id));
if(it != signal_map.end())
{
    it->second = stats;
}

这在大部分情况下都有效,其中正确的 Id 映射到相应的统计信息结构。有时,我会遇到不正确的匹配,其中处理程序 A 的 ID 被分配给属于处理程序 B 的结构。在我看来,该函数是并行调用的。我的印象是,在线程中,对函数的调用虽然是并行完成的,但却是重复的。不是这种情况,还是在线程中通过引用传递值存在问题?

如果没有某种形式的保护,防止多个线程同时修改map,则无法从多个线程更新std::map。你需要一个互斥锁或类似的东西。特别是,如果id是"新的",那么映射中的底层数据结构(通常是"RB树")将被更改。这不能从多个线程完成。在修改树时,您也无法访问树以"读取",因为树中的条目可能是"半更新"的(例如,下一个元素指向尚未正确填充的元素或类似元素)。

最新更新