如何在初始值设定项列表中锁定互斥对象
How can I lock a mutex in an initializer list?
我有一个ConcurrentQueue
类,它基于用户提供的容器,具有这样的构造函数。。。
ConcurrentQueue(const ConcurrentQueue& other) : m_Queue(other.m_Queue) {}
但是,我需要在复制other
的互斥对象时锁定它。
选项1:
所以我根本不能使用复制构造函数,并且做…
ConcurrentQueue(const ConcurrentQueue& other) : m_Queue(other.m_Queue)
{
std::lock_guard<std::mutex> lock(other.m_Mutex);
m_Queue = other.m_Queue;
}
但我不能保证复制赋值和复制构造是等效的功能。
选项2:
我可以有一个私人的方法。。。
std::queue<T, Container> GetQueue() const
{
std::lock_guard<std::mutex> lock(other.m_Mutex);
return m_Queue;
}
然后在构造函数中执行此操作。。。
ConcurrentQueue(const ConcurrentQueue& other) : m_Queue(other.GetQueue()) {}
但这可能(取决于优化(使用m_Queue的复制构造函数一次,移动构造函数一次。我也不能保证一份副本和一次移动就等于一份副本。此外,用户提供的容器可能很奇怪,可以复制但不可移动,这也会导致这种方法出现问题。
那么,我该怎么办?
ConcurrrentQueue::ConcurrrentQueue(
ConcurrrentQueue const& other )
: m_Queue( (std::lock_guard<std::mutex>( other.m_Mutex ),
other.m_Queue ) )
{
}
应该起作用。
锁定,创建内容的副本,然后与成员交换。至少这是最简单和IMHO最干净的方法。另一种不太干净的方法是使用逗号运算符:(a, b)
产生b
,但如果a
是作用域锁,则临时锁将一直存在到下一个序列点,即,直到您使用b
初始化本地副本。
也就是说,有两件事需要考虑:
- 也许无论如何,复制并不是一个明智的想法,如果你只是禁用复制,你的设计也会很好
- 如果您有权访问队列,并且可以读取它进行复制,这难道不意味着互斥锁一定已经被锁定了吗?如果不是,你如何确定你真的想复制队列?我不质疑是否有答案可以证明这个设计是合理的,但这很不寻常
相关文章:
- Pybind11:将元组列表从Python传递到C++
- 从链接列表c++中删除一个项目
- 如何(从固定列表中)选择一个数字序列,该序列将与目标数字相加
- C++如何通过用户输入删除列表元素
- 读取文件的最后一行并输入到链接列表时出错
- 复制列表初始化的隐式转换的等级是多少
- 如何找到锁定Linux futex的C++行
- LNK2038、MSVS2017 MAGMA的原因列表
- 不能在初始值设定项列表中将非常量表达式从类型 'int' 缩小到'unsigned long long'
- 没有为自己的结构调用列表推回方法
- G锁定铸造到基础上会释放模拟行为
- 使用简单类型列表实现的指数编译时间.为什么
- 一对向量构造函数:初始值设定项列表与显式构造
- 标准是否使用多余的大括号(例如 T{{{10}}})定义列表初始化?
- 通过for循环使用用户输入填充列表
- 如何锁定使用具有初始化列表的构造函数的类的成员函数
- 如何在C++中滚动锁定报表样式列表视图的第一列
- 标记了 C 中的锁定免费列表的指针
- 如何在初始值设定项列表中锁定互斥对象
- 我可以锁定列表中的一个元素以使其线程安全,而不是锁定整个列表吗?