gpt4 book ai didi

multithreading - 使用互锁增量来增量STL映射的value字段。它是线程安全的吗?

转载 作者:行者123 更新时间:2023-12-03 13:12:39 26 4
gpt4 key购买 nike

我有这样定义的 map 。

typedef std::map< tstring, unsigned int >  ErrorToCount_T;
ErrorToCount_T m_ErrorToSuppress;

我正在这样使用。
ErrorToCount_T::iterator itr = m_ErrorToSuppress.find( val );
if( itr != m_ErrorToSuppress.end())
{
if( (itr->second) % m_LogFreq == 0)
//Do something
else
//Do something else
InterlockedIncrement( &itr->second);
}

我看到了 this,并且我知道find是线程安全的。但是我在想InterlockedIncrement(&itr-> second)也将是线程安全的吗?上面的代码线程是否安全。
在多线程环境中,此映射中绝对没有插入。

最佳答案

如果两个线程使用相同的键(即val)执行代码,则以下列表中标记为(1)(2)的表达式可能会同时执行:

if( (itr->second) % m_LogFreq == 0) // (1)
//Do something
else
//Do something else
InterlockedIncrement( &itr->second); // (2)

(1)表达式中,将读取存储位置 itr->second,在 (2)表达式中将其写入。这就是所谓的数据争用,而C++ 11标准指出,如果程序的行为包含数据争用,则其行为是不确定的。

只要您的编译器供应商没有为您提供有关内存模型的其他保证,您就必须使用不会引起数据争用的操作。使用C++ 11,它可能如下所示:
using ErrorToCount = std::map<tstring, std::atomic<unsigned int>>;
ErrorToCount errorToSuppress;

ErrorToCount::iterator itr = errorToSuppress.find( val );
if( itr != errorToSuppress.end()) {
if (itr->second.load(std::memory_order_seq_cst) % m_LogFreq == 0)
//Do something
else
//Do something else
itr->second.fetch_add(1, std::memory_order_seq_cst);
}

关于multithreading - 使用互锁增量来增量STL映射的value字段。它是线程安全的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24121087/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com