dar*_*mos 5 c++ windows queue concurrency blocking
我正在尝试实现一个队列,如果它是空的,则阻塞Pop操作,并在推送新元素时立即解除阻塞.我担心我可能会遇到一些竞争条件; 我试着看看其他一些实现,但我发现大多数是在.NET中完成的,而我发现的少数C++在很大程度上依赖于其他库类.
template <class Element>
class BlockingQueue{
DRA::CommonCpp::CCriticalSection m_csQueue;
DRA::CommonCpp::CEvent m_eElementPushed;
std::queue<Element> m_Queue;
public:
void Push( Element newElement ){
CGuard g( m_csQueue );
m_Queue.push( newElement );
m_eElementPushed.set();
}
Element Pop(){
{//RAII block
CGuard g( m_csQueue );
bool wait = m_Queue.empty();
}
if( wait )
m_eElementPushed.wait();
Element first;
{//RAII block
CGuard g( m_csQueue );
first = m_Queue.front();
m_Queue.pop();
}
return first;
}
};
Run Code Online (Sandbox Code Playgroud)
一些解释到期:
我担心使用Pop()时可能会出现一些奇怪的竞争情况.你们有什么感想?
更新:由于我正在使用Visual Studio 2010(.NET 4.0),我最终使用了C++运行时提供的unbounded_buffer类.当然,我使用Pointer to Implementation Idiom(Chesire Cat)将它包装在一个类中,以防我们决定更改实现或需要将此类移植到另一个环境
这不是线程安全的:
{//RAII block
CGuard g( m_csQueue );
bool wait = m_Queue.empty();
}
/// BOOM! Other thread ninja-Pop()s an item.
if( wait )
m_eElementPushed.wait();
Run Code Online (Sandbox Code Playgroud)
注意BOOM评论的位置.事实上,其他地方也是可以想象的(之后if).在任何一种情况下,后续front和pop调用都将失败.