Ale*_*lex 6 c++ concurrency multithreading c++11 c++14
我使用std::map并获得一个我可以使用的元素:http://www.cplusplus.com/reference/map/map/
iterator find (const key_type& k);mapped_type& at (const key_type& k);mapped_type& operator[] (const key_type& k);还是:lower_bound()或者equal_range()- 和find()这种情况一样.
我不能用:
at() - 因为它抛出异常,我测量了10倍的性能下降operator[] - 因为它插入一个元素(如果它不存在),这种行为是不可接受的find() - 是我想要的.但我std::map在多线程程序中使用并通过锁保护它std::mutex.
还有std::map其他线程的插入和删除.
我应该保护std::map::end还是保证它对于一个分配的容器总是相同的?
我可以使用static auto const map_it_end = map1.end();不受保护的此类物品std::mutex吗?
#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;
}
Run Code Online (Sandbox Code Playgroud)
http://www.cplusplus.com/reference/map/map/end/
数据竞争访问容器(const和非const版本都不会修改容器).调用不访问包含的元素,但返回的迭代器可用于访问或修改元素.同时访问或修改不同的元素是安全的.
Jon*_*ely 11
我应该保护
std::map::end还是保证它对于一个分配的容器总是相同的?
从技术上讲,任何对成员函数的调用都必须受到互斥锁的保护,如果它可能与任何非const成员函数同时发生.因此,如果任何线程可以插入或擦除元素,那么在end()不锁定互斥锁的情况下调用是不安全的.
我可以使用
static auto const map_it_end = map1.end();不受保护的此类物品std::mutex吗?
在某些情况下,您可以缓存过去的迭代器,因为std::map插入和擦除不会使a的过去的迭代器无效,只能通过交换或移动映射.
但你为什么要这样做?缓慢的操作find()不是end(),所以如果你end()在仍然持有互斥锁的时候打电话,那么肯定会有效.
如果其他线程可能正在擦除元素,那么您需要在取消引用返回的迭代器时保持互斥锁,find()以确保它不会被另一个删除它引用的元素的线程无效.因此,end()当您已经锁定互斥锁时,拨打电话不会成为问题.