C ++的std::mutex
没有移动构造函数。有一个good reason for that。基本上,移动构造函数本身通常不是线程安全的,并且互斥体的全部意义在于多个线程将尝试同时访问它。
不幸的是,互斥锁不能直接放入容器中。容器需要能够安全地移动其内容,而您无法使用互斥锁。
简单的方法是用一个单独的互斥锁保护整个容器。但是假设我想要比那更精细的控制?如果我通过容器实现数据库(例如:std::map
),那么希望能够锁定单个记录而不仅仅是整个数据库似乎是合理的。
我想到的下一件事就是使用std::unique_ptr
解决问题。那会编译,但它并没有真正改变基本问题,是吗?移动存在问题的情况是thread1
进行容器更改导致条目移动而thread2
正在使用该容器条目。在这种情况下,thread2
可能很容易最终持有被破坏的条目或智能指针。似乎无论如何,你最终都必须在做任何事情之前使用互斥锁来锁定整个容器。
似乎应该有一种已知的习惯用于做这些事情。
答案 0 :(得分:1)
互斥锁不需要移动:
想象一下,地图中的每一行都是:
template <class T>
class row
{
shared_ptr<mutex> m;
T data;
...
};
因此,如果需要移动或复制行,则没有问题。
然后,您可以从每个进程访问互斥锁以访问数据。
当然,您需要一个全局互斥锁来对整个地图执行更改:insert / delete / [] /任何其他更改地图状态的操作。
编辑:
遵循每行中带有互斥锁的代码的简单示例。 (它没有实现只有数据结构的任何其他内容)
#include <memory>
#include <map>
#include <mutex>
template <class T>
class row
{
std::shared_ptr<std::mutex> m;
T data;
public:
row( std::shared_ptr<std::mutex> mut): m(mut){};
};
auto main () -> int
{
std::shared_ptr<std::mutex> mut(new std::mutex);
std::map<int,row<int>> db;
row<int> a(mut);
db.insert(std::pair<int, row<int>>(1, a));
return 0;
}