std::unique_ptr 的 STL 容器中 find() 的线程安全
thread safety of find() from a STL container of std::unique_ptr
示例代码。
class Obj
{
public:
void doSome(void)
{
std::cout << "Hello World!" << std::endl;
}
};
std::unordered_map<int, std::unique_ptr<Obj>> map;
// insert -- done with single thread and before find()
map[123] = std::move( std::unique_ptr<Obj>(new Obj) );
// find -- run from multiple threads
auto search = map.find(123); // <=== (Q)
if (search != map.end())
{
search->second->doSome();
}
(问)
如果有多个线程,线程安全性如何运行 //find section with map.find(123)?
将map.find(123)总是在每个线程[=26=中找到obj ]?只要search->second不分配给别人就可以了?
find()
和无序映射中的任何其他方法都不是线程安全的。如果一个执行线程可能调用 find()
而任何其他线程调用任何修改它的无序映射方法,这将导致未定义的行为。
如果多个执行线程使用相同的键调用 find()
,前提是没有未定义的行为,所有执行线程都将获得相同的键值。
当多个线程访问同一个变量并且其中至少有一个线程写入它时,就会发生数据竞争。这里不是这种情况,每个人都在读取相同的数据。没关系。不过,还有另一个问题未在此代码中解决:根据数据存储到地图对象的时间,某些线程可能看不到地图对象的更新版本。处理此同步问题的最简单方法是在创建任何 reader 线程之前设置地图对象。
示例代码。
class Obj
{
public:
void doSome(void)
{
std::cout << "Hello World!" << std::endl;
}
};
std::unordered_map<int, std::unique_ptr<Obj>> map;
// insert -- done with single thread and before find()
map[123] = std::move( std::unique_ptr<Obj>(new Obj) );
// find -- run from multiple threads
auto search = map.find(123); // <=== (Q)
if (search != map.end())
{
search->second->doSome();
}
(问)
如果有多个线程,线程安全性如何运行 //find section with map.find(123)?
将map.find(123)总是在每个线程[=26=中找到obj ]?只要search->second不分配给别人就可以了?
find()
和无序映射中的任何其他方法都不是线程安全的。如果一个执行线程可能调用 find()
而任何其他线程调用任何修改它的无序映射方法,这将导致未定义的行为。
如果多个执行线程使用相同的键调用 find()
,前提是没有未定义的行为,所有执行线程都将获得相同的键值。
当多个线程访问同一个变量并且其中至少有一个线程写入它时,就会发生数据竞争。这里不是这种情况,每个人都在读取相同的数据。没关系。不过,还有另一个问题未在此代码中解决:根据数据存储到地图对象的时间,某些线程可能看不到地图对象的更新版本。处理此同步问题的最简单方法是在创建任何 reader 线程之前设置地图对象。