我倾向于使用我称之为“同步队列”的东西。我换了正常的队列,并使用Semaphore类两个锁,使读取块,就像你的愿望:
#ifndef SYNCQUEUE_20061005_H_
#define SYNCQUEUE_20061005_H_
#include <queue>
#include "Semaphore.h"
// similar, but slightly simpler interface to std::queue
// this queue implementation will serialize pushes and pops
// and block on a pop while empty (as apposed to throwing an exception)
// it also locks as neccessary on insertion and removal to avoid race
// conditions
template <class T, class C = std::deque<T> > class SyncQueue {
protected:
std::queue<T, C> m_Queue;
Semaphore m_Semaphore;
Mutex m_Mutex;
public:
typedef typename std::queue<T, C>::value_type value_type;
typedef typename std::queue<T, C>::size_type size_type;
explicit SyncQueue(const C& a = C()) : m_Queue(a), m_Semaphore(0) {}
bool empty() const { return m_Queue.empty(); }
size_type size() const { return m_Queue.size(); }
void push(const value_type& x);
value_type pop();
};
template <class T, class C>
void SyncQueue<T, C>::push(const SyncQueue<T, C>::value_type &x) {
// atomically push item
m_Mutex.lock();
m_Queue.push(x);
m_Mutex.unlock();
// let blocking semaphore know another item has arrived
m_Semaphore.v();
}
template <class T, class C>
typename SyncQueue<T, C>::value_type SyncQueue<T, C>::pop() {
// block until we have at least one item
m_Semaphore.p();
// atomically read and pop front item
m_Mutex.lock();
value_type ret = m_Queue.front();
m_Queue.pop();
m_Mutex.unlock();
return ret;
}
#endif
您可以实现信号量和互斥,在你的线程执行相应的原语。
注意:这个实现是一个队列中单个元素的例子,但是你可以很容易地用一个缓存结果的函数来包装它,直到N被提供。像这样的东西,如果它是一个字符队列:
std::vector<char> func(int size) {
std::vector<char> result;
while(result.size() != size) {
result.push_back(my_sync_queue.pop());
}
return result;
}
好的开始,但请记住我希望我的阅读成功。不能保证`push_em_in`会保存足够的数据以便发生。所以阅读需要等到足够了。这是我想确保高效(不旋转)的循环。 – 2008-10-15 23:19:09
您也可以使用RAII来确保您的锁()unlock()是异常安全的。 – 2008-10-15 23:20:30
@Frank对这个概念采取了另一种方式。你现在更好地学习如何更好地使用pthread mutex吗? – 2008-10-15 23:24:41