[英]How can I lock a mutex in an initializer list?
I have a ConcurrentQueue
class that is based around a user provided container with a constructor like this... 我有一个
ConcurrentQueue
类,它基于用户提供的容器,带有这样的构造函数...
ConcurrentQueue(const ConcurrentQueue& other) : m_Queue(other.m_Queue) {}
But, I need to lock other
's mutex while it's being copied. 但是,我需要在复制时锁定
other
的互斥锁。
Option 1: 选项1:
So I could not use the copy constructor at all, and do... 所以我根本不能使用复制构造函数,并且......
ConcurrentQueue(const ConcurrentQueue& other) : m_Queue(other.m_Queue)
{
std::lock_guard<std::mutex> lock(other.m_Mutex);
m_Queue = other.m_Queue;
}
But I can't guarantee that copy assignment and copy construction are equivalent functionality. 但我不能保证复制分配和复制构造是等效的功能。
Option 2: 选项2:
I could have a private method... 我可以有私人方法......
std::queue<T, Container> GetQueue() const
{
std::lock_guard<std::mutex> lock(other.m_Mutex);
return m_Queue;
}
And then in the constructor do this... 然后在构造函数中执行此操作...
ConcurrentQueue(const ConcurrentQueue& other) : m_Queue(other.GetQueue()) {}
But this potentially (depending on optimizations) uses m_Queue's copy constructor once and it's move constructor once. 但这可能(取决于优化)使用m_Queue的复制构造函数一次,它移动构造函数一次。 And I also can't guarantee that a copy and a move is equivalent to just a copy.
我也不能保证副本和移动只相当于副本。 Additionally the user provided container could be bizarre and be copyable but unmoveable, which would also cause this approach to have problems.
此外,用户提供的容器可能是奇怪的并且是可复制的但是不可移动的,这也会导致这种方法出现问题。
So, what do I do? 那么,我该怎么办?
ConcurrrentQueue::ConcurrrentQueue(
ConcurrrentQueue const& other )
: m_Queue( (std::lock_guard<std::mutex>( other.m_Mutex ),
other.m_Queue ) )
{
}
should work. 应该管用。
Lock, create a copy of the content and then swap it with the member. 锁定,创建内容的副本,然后将其与成员交换。 At least that's the easiest and IMHO cleanest way.
至少那是最简单和恕我直言最干净的方式。 Another less clean way is to use the comma operator:
(a, b)
yields b
, but if a
is a scoped lock, the temporary will live until the next sequence point, ie until you have used b
to initialize your local copy. 另一个不太干净的方法是使用逗号运算符:
(a, b)
产生b
,但如果a
是一个范围锁,临时将一直存在直到下一个序列点,即直到你用b
来初始化本地副本。
That said, there are two things to consider: 也就是说,有两件事需要考虑:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.