简体   繁体   English

从std :: unique_ptr的STL容器中查找find()的安全性

[英]thread safety of find() from a STL container of std::unique_ptr

Example code. 示例代码。

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();
}

(Q) (Q)

How about the thread safty if there are multiple threads running //find section with map.find(123) ? 如果有多个线程在运行//找到带有map.find(123)的部分, 那么线程安全性怎么样?

will map.find(123) always find the obj in every thread ? map.find(123)总是在每个线程中找到obj as long as the search->second not assigned to someone else? 只要搜索 - >第二次没有分配给别人?

When more than one thread accesses the same variable and at least one of them writes to it you have a data race. 当多个线程访问同一个变量并且至少有一个线程写入它时,您就会遇到数据争用。 That's not the case here, where everyone is reading the same data. 这不是这里的情况,每个人都在阅读相同的数据。 That's okay. 没关系。 There's another issue, though, which isn't addressed in this code: depending on when the data is stored into the map object, some threads might not see the updated version of the map object. 但是,还有另一个问题,在此代码中没有解决:根据数据何时存储到地图对象中,某些线程可能看不到地图对象的更新版本。 The simplest way to deal with this synchronization problem is to set up the map object before creating any of the reader threads. 处理此同步问题的最简单方法是在创建任何读取器线程之前设置映射对象。

Neither find() , nor any other method in the unordered map is thread safe. find()或无序映射中的任何其他方法都不是线程安全的。 If it's possible for one execution thread to call find() while any other thread calls any unordered map method that modifies it, this results in undefined behavior. 如果一个执行线程可以调用find()而任何其他线程调用任何修改它的无序map方法,则会导致未定义的行为。

If multiple execution threads are calling find() with the same key, provided that there is no undefined behavior all execution threads will get the same value for that key. 如果多个执行线程使用相同的键调用find() ,只要没有未定义的行为,所有执行线程将获得该键的相同值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM