我傾向於使用我稱之爲「同步隊列」的東西。我換了正常的隊列,並使用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