我试图实现一个队列,阻止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; } };
一些解释是由于:
CCriticalSection是Windows临界区的包装,方法Enter和Leave是私人的,而CGuard是它唯一的朋友
CGuard是CCriticalSection的RAII包装器,进入构造器的关键部分,将其留在析构器上
CEvent是Windows事件的包装,等待使用WaitForSingleObject函数
我不介意元素是通过价值传递的,它们是小对象
我不能使用Boost,只是Windows的东西(因为我已经用CEvent和CGuard做了)
恐怕在使用Pop()时可能会出现一些奇怪的竞态条件。 你们有什么感想?
更新 :因为我在Visual Studio 2010(.NET 4.0)上工作,我最终使用C ++运行时提供的unbounded_buffer类。 当然,我使用指向实现语言(Chesire Cat)的指针将其包装在一个类中,以防万一我们决定更改实现或需要将此类移植到另一个环境
Linux内核中wait_event和wake_up之间的争用条件
如何增加数字海洋液滴中的并发请求?
在Linux中的“写”function的问题
并发访问大量的项目
一个node.js集群在64位Wintel PC上产生多less个subprocess?
可以去外部进程产卵和沟通,而无需启动每个外部进程的一个OS线程?
为什么“超级”Linux服务器与笔记本电脑Win7上的multithreadingJava程序不能更快?
当中央资源库位于Windows文件共享中时,将多个用户使用git是否安全?
.NET或Windows同步基元性能规范
这不是线程安全的:
{//RAII block CGuard g( m_csQueue ); bool wait = m_Queue.empty(); } /// BOOM! Other thread ninja-Pop()s an item. if( wait ) m_eElementPushed.wait();
注意BOOM评论的位置。 事实上,其他地点也是可以想像的(之后的if )。 在任何一种情况下,随后的front和pop呼叫都将失败。
条件变量应该是有用的,如果你的目标是最新的Windows版本。 这通常使实现阻塞队列更简单。
在这里看看使用Boost的类似队列的设计 – 即使你不能使用Boost或条件变量,一般的指导和后续的讨论应该是有用的。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。