我有这样定义的 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/