在我看来,这两种方法都不太理想。我倾向于使用简单的指针而不是迭代器。但是,在 deque 中按值 存储您正在处理的对象时,使用迭代器/指针是有问题的。
如果您将框架对象按值存储在 deque 中,这是否意味着它们复制起来很便宜?他们可以移动吗?如果是这样,我很想在处理之前将它们复制/移出 deque,以便您更快地释放锁。
或者,您可以将 指针 存储到 deque 中的帧而不是值。
无论哪种方式,您发布的方法的问题在于,如果在您锁定 mutex 之后但在解锁 之前发生异常,则它不是 异常安全双端队列 将保持锁定状态。它还会锁定 deque 以延长处理时间:
// not exception safe
mtxlock.lock();
// Taking the address means locking the whole queue
// until you have finished with the one element
VideoFrame* pFrame = &p_inputQueue->front();
//A very long computing process using pointer *pFrame
p_inputQueue->pop_front();
// not exception safe
mtxlock.unlock();
我倾向于从 deque 复制/移动对象并使用std::lock_guard 来确保异常安全(如果出现异常,它将自动释放锁)
// ready to copy/move the object by value
VideoFrame frame;
{ // start a new block for the lock
// get a local automatic lock
std::lock_guard<std::mutex> lock(mtxlock);
// copy/move the object out of the queue
// so you can release the lock immediately
frame = std::move(p_inputQueue->front());
p_inputQueue->pop_front();
} // lock is released here
// Now it doesn't matter how long it takes
// to process the object
或者将 pointers 存储在 deque 中:
// store pointers in the queue
VideoFrame* pFrame;
{ // start a new block for the lock
// get a local automatic lock
std::lock_guard<std::mutex> lock(mtxlock);
// copy the pointer out of the queue
// so you can release the lock immediately
pFrame = p_inputQueue->front();
p_inputQueue->pop_front();
} // lock is released here
// Now it doesn't matter how long it takes
// to process the object
如果您决定将指针存储在 deque 中,那么我建议您使用 智能指针,例如 std::unique_ptr。这相当于您按 value 存储框架:
// store unique pointers in the queue
std::deque<std::unique_ptr<VideoFrame>>* p_inputQueue;
// ...
std::unique_ptr<VideoFrame> pFrame;
{ // start a new block for the lock
// get a local automatic lock
std::lock_guard<std::mutex> lock(mtxlock);
// move the unique pointer out of the queue
// so you can release the lock immediately
pFrame = std::move(p_inputQueue->front());
p_inputQueue->pop_front();
} // lock is released here
// Now it doesn't matter how long it takes
// to process the object