我有一个std :: map,多个线程用它来存储数据.地图声明如下:
std::map<int, Call> calls;
Run Code Online (Sandbox Code Playgroud)
从每个线程,我必须获取互斥锁,获取指向或属于该线程的对象的引用,然后释放互斥锁.之后我可以修改对象,因为每个对象只由一个线程使用.一旦线程死亡,地图中的相应对也将被删除.
我想知道实现这个的最佳方法.我在考虑两种方式:
1)我知道这个人看起来非常疯狂,但仍然
std::map<int, Call> calls;
...
{
mutex.lock();
Call* callptr = &calls[id];
mutex.unlock();
// use callptr
}
Run Code Online (Sandbox Code Playgroud)
或2)我觉得这个看起来更明智
std::map<int, std::auto_ptr<Call> > calls;
...
{
mutex.lock();
std::auto_ptr<Call> callptr = map[id];
mutex.unlock();
// use callptr
mutex.lock();
map[id] = callptr;
mutex.unlock();
}
Run Code Online (Sandbox Code Playgroud)
线程实际上是在不同的dll中创建的,我没有代码.我正在编写的这个dll由该dll导入并使用.所以它必须只用std :: map实现,但是有人可以告诉我其中一种方法是否正常,或者是否有办法使它更稳定.
谢谢
你应该使用迭代器:
mutex.lock();
std::map<int, Call>::iterator callptr = calls.find(id);
callptr->second.foo();
...
mutex.unlock();
Run Code Online (Sandbox Code Playgroud)
你的第一个带指针的解决方案是有问题的,因为地图中对象的生命周期是不确定的 - 当插入或删除元素时重新平衡树时,可能会移动它.
你的第二个解决方案将不会在所有的工作,因为std::auto_ptr
不满足要求mapped_type
的std::map
-主要是因为它的拷贝构造函数和operator=
不实际拷贝.您可能不会收到编译器错误,但在运行时会出现非常奇怪的行为.