T.E*_*.D. 14 c++ multithreading stl c++11
C++ std::mutex没有移动构造函数.这是有充分理由的.基本上,移动构造函数本身通常不是线程安全的,并且互斥体的全部意义在于多个线程将尝试同时访问它.
不幸的是,互斥不能直接放入容器中.容器需要能够安全地移动其内容,而您不能使用互斥锁.
简单的方法是用一个单独的互斥锁保护整个容器.但是假设我想要比那更精细的控制?如果我通过容器(例如:)实现数据库std::map,那么想要锁定单个记录的能力似乎是合理的,而不仅仅是整个数据库.
我想到的下一件事就是通过使用来破解问题std::unique_ptr.那会编译,但它并没有真正改变基本问题,是吗?移动存在问题的情况是,在使用该容器条目时,容器thread1更改会导致条目移动thread2.在这种情况下,thread2可能很容易最终持有一个被破坏的条目或智能指针.似乎无论如何,你最终都必须在做任何事情之前用互斥锁锁定整个容器.
似乎应该有一个已知的习惯用于做这些事情.
互斥锁不需要移动:
想象一下地图中的每一行都是这样的:
template <class T>
class row
{
shared_ptr<mutex> m;
T data;
...
};
Run Code Online (Sandbox Code Playgroud)
因此,如果您的行需要移动或复制,没有问题。
然后,您可以从每个进程访问互斥体来访问数据。
当然,您需要一个全局互斥体来对整个映射执行更改:插入/删除/[]/任何其他更改映射状态的操作。
编辑:
下面是每行都有互斥体的简单代码示例。(它除了数据结构之外没有实现其他任何东西)
#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;
}
Run Code Online (Sandbox Code Playgroud)