我的实施存在缺陷,我无法弄清楚。我有一个工作线程,不一致地调用回调写入名为" m_bufferLatest"的缓冲区。需要复制缓冲区,并且在主线程中完成复制需要一些时间。所以我需要保护" m_bufferLatest"。所以在我调用ContinuousCapture()的主线程中,我设置了一个名为" m_skipFrame"的标志。这样回调生病不会写入m_bufferLatest。
但是当我运行我的程序时,m_bufferLatest为null,具体取决于工作线程的运行速度。
有人可以帮我解决一下我的程序有什么问题吗?
bool HandleEofCallbackCont()
{
std::lock_guard<std::mutex> lock(m_EofMutex);
if (!m_skipFrame) {
//here update m_bufferCont
if (!m_camera->SaveLatestFrameToQueue())
{
printf("get latest frame failed.. \n");
}
}
m_EofFlag = true;
}
m_EofCond.notify_one();
return true;
}
bool ContinuousCapture(Settings settings)
{
//wait for the condition variable otherwise timeout
std::unique_lock<std::mutex> lock(m_EofMutex);
{
if (!m_EofFlag)
{
m_EofCond.wait_for(lock, std::chrono::seconds(10), [&]() {
return (m_EofFlag);
});
}
m_skipFrame = true;
int size = m_camera->m_bufferBytes / sizeof(uns16);
//transfer from data
if (!TransferData(settings, (uns16*)m_camera->m_bufferLatest, size, m_Frame))
{
printf("transfer data failed");
return false;
}
m_skipFrame = false;
m_EofFlag = false;
}
return true;
}
答案 0 :(得分:0)
为了在两个线程之间进行同步,使用同步原语非常重要。还可以减少系统被互斥锁锁定的时间。虽然互斥锁允许在不同线程之间保证状态,但它们倾向于表现出单线程性能。
m_SkipFrame = true;
在一个线程上可见,但需要发生某种形式的interthread-happens-before
以确保其他线程不起作用。
std::atomic<> is a good mechanism, for testing state between the threads.
假设你只有一个读者和一个作家。以下方案最简单。
假设一个类持有缓冲区。
class BufferHolder {
};
然后在Interthread类中
class Interthread {
std::atomic<BufferHolder*> m_Exchange;
}
那么作家就是......
void Interthread::Writer( BufferHolder * pNewBuffer ) {
BufferHolder * oldBuffer = m_Exchange.exchange( pNewBuffer );
delete oldBuffer; // may be nullptr, but that is ok.
// if the oldBuffer wasn't used, it was sort of wasted.
}
BufferHolder * Interthread::Reader() {
BufferHolder * pNewBuffer = m_Exchange.exchange( nullptr );
return pNewBuffer;
}
您可能需要一个队列或某种机制来存储固定数量的缓冲区。