gpt4 book ai didi

c++ - std::map::end 是线程安全的并且保证对于同一个容器它总是相同的吗?

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:10:53 24 4
gpt4 key购买 nike

我使用 std::map 并获取我可以使用的单个元素:http://www.cplusplus.com/reference/map/map/

另外:lower_bound()equal_range() - 在这种情况下与 find() 相同。

我不能使用:

  • at() - 因为它抛出异常,我测量了 10 倍的性能下降
  • operator[] - 因为它插入一个不存在的元素,所以这种行为是 Not Acceptable

find() - 是我想要的。但是我在多线程程序中使用std::map,并通过锁std::mutex来保护它。

还有从其他线程插入和删除 std::map

我应该保护std::map::end吗?或者保证对于一个分配的容器它总是相同的?

我可以使用不受 std::mutex 保护的类似 static auto const map_it_end = map1.end(); 的东西吗?

http://ideone.com/tATn0H

#include <iostream>
#include <string>
#include <mutex>
#include <thread>
#include <map>

std::map<std::string, std::string> map1 ( {{"apple","red"},{"lemon","yellow"}} );
static auto const map_it_end = map1.end();
std::mutex mtx1;

void func() {
std::lock_guard<std::mutex> lock1(mtx1);

auto it1 = map1.find("apple");
if(it1 != map_it_end) // instead of: if(it1 != map1.end())
std::cout << it1->second << ", ";
}

int main ()
{
std::thread t1(func);
std::thread t2(func);
t1.join();
t2.join();

return 0;
}

http://www.cplusplus.com/reference/map/map/end/

Data races The container is accessed (neither the const nor the non-const versions modify the container). No contained elements are accessed by the call, but the iterator returned can be used to access or modify elements. Concurrently accessing or modifying different elements is safe.

最佳答案

Should I protect std::map::end or is guaranteed that it always the same for one allocated container?

从技术上讲,任何对成员函数的调用都必须受到互斥量的保护,如果它可能与任何非常量成员函数同时发生的话。因此,如果任何线程可以插入或删除元素,那么在不锁定互斥体的情况下调用 end() 是不安全的。

Can I use something like this static auto const map_it_end = map1.end(); which is not protected by std::mutex?

在某些情况下,您可以缓存尾后迭代器,因为 std::map 的尾后迭代器不会因插入和删除而失效,只有可能通过交换或移动 map 。

但是你为什么要这么做?缓慢的操作是 find() 而不是 end(),因此如果您在仍然持有互斥量的同时调用 end() 那么它肯定会起作用.

如果其他线程可能正在删除元素,那么您需要在取消引用 find() 返回的迭代器时保持互斥锁,以确保它不会被另一个删除它的元素的线程无效指的是。因此,再次调用 end() 不会成为问题,因为您已经锁定了互斥量。

关于c++ - std::map::end 是线程安全的并且保证对于同一个容器它总是相同的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38214379/

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