c ++通过迭代器映射线程安全行为
c++ map threadsafe behavior through iterator
我的需求如下:
一个线程(名为线程 1)只是不断地将对插入到公共映射中。
而另一个线程(名为线程 2)一直在开始位置获取元素(无论它是否仍然是开始,而其他线程在开始位置插入一个元素)并对元素进行一些操作并擦除迭代器。
我知道 STL 不是线程安全的,但它仍然是一个很好用的容器。所以我的方法是每次线程 2 获取元素时,我都会复制它并完成我的工作,并用一个互斥体保护 insert/delete/begin/end。
c++17下的伪代码
my_map {
insert(){
lock_guard(mutex)
map.insert()
}
erase(){
lock_guard(mutex)
map.erase()
}
end(){
lock_guard(mutex)
map.end()
}
begin(){
lock_guard(mutex)
map.begin()
}}
thread 1:
while(1){
sleep(1)
my_map.insert()
}
thread 2:
while(1){
auto it = my_map.begin()
auto k = it->first;
auto v = it->second;
work(k, v);
my_map.erase(it);
}
我的问题是我的代码是线程安全的吗?并且在线程 1 中插入会影响线程 2 中 k 和 v 的实际值吗?(同样,无论它是否处于真正的开始位置,我只想在线程 2 使用“auto it”时获取迭代器的 k 和 v = my_map.begin()")
如果底层映射是 std::unordered_map
,则它不是线程安全的。使用 unordered_map
insert
可能会使迭代器无效(如果发生 rehasing)。
使用 std::map
迭代器不会在 insert
上失效,所以我认为代码没问题。
我的需求如下: 一个线程(名为线程 1)只是不断地将对插入到公共映射中。 而另一个线程(名为线程 2)一直在开始位置获取元素(无论它是否仍然是开始,而其他线程在开始位置插入一个元素)并对元素进行一些操作并擦除迭代器。
我知道 STL 不是线程安全的,但它仍然是一个很好用的容器。所以我的方法是每次线程 2 获取元素时,我都会复制它并完成我的工作,并用一个互斥体保护 insert/delete/begin/end。
c++17下的伪代码
my_map {
insert(){
lock_guard(mutex)
map.insert()
}
erase(){
lock_guard(mutex)
map.erase()
}
end(){
lock_guard(mutex)
map.end()
}
begin(){
lock_guard(mutex)
map.begin()
}}
thread 1:
while(1){
sleep(1)
my_map.insert()
}
thread 2:
while(1){
auto it = my_map.begin()
auto k = it->first;
auto v = it->second;
work(k, v);
my_map.erase(it);
}
我的问题是我的代码是线程安全的吗?并且在线程 1 中插入会影响线程 2 中 k 和 v 的实际值吗?(同样,无论它是否处于真正的开始位置,我只想在线程 2 使用“auto it”时获取迭代器的 k 和 v = my_map.begin()")
如果底层映射是 std::unordered_map
,则它不是线程安全的。使用 unordered_map
insert
可能会使迭代器无效(如果发生 rehasing)。
使用 std::map
迭代器不会在 insert
上失效,所以我认为代码没问题。