我需要C++中的阻塞隊列,並具有超時功能offer()
。該隊列旨在用於多個生產者,一個消費者。當我執行時,我沒有發現任何適合這種需求的現有隊列,所以我自己編寫了它。C++阻塞隊列Segfault w/Boost
我看到segfaults出隊列上的take()
方法,但它們是間歇性的。我一直在研究代碼問題,但我沒有看到任何看起來有問題的東西。
我想知道如果:
- 有是不可靠的這種現有的庫,我應該 使用(升壓或頭只首選)。
- 任何人都看到我需要修復的代碼中有任何明顯的缺陷。
這裏是標題:
class BlockingQueue
{
public:
BlockingQueue(unsigned int capacity) : capacity(capacity) { };
bool offer(const MyType & myType, unsigned int timeoutMillis);
MyType take();
void put(const MyType & myType);
unsigned int getCapacity();
unsigned int getCount();
private:
std::deque<MyType> queue;
unsigned int capacity;
};
和相關的實現:
boost::condition_variable cond;
boost::mutex mut;
bool BlockingQueue::offer(const MyType & myType, unsigned int timeoutMillis)
{
Timer timer;
// boost::unique_lock is a scoped lock - its destructor will call unlock().
// So no need for us to make that call here.
boost::unique_lock<boost::mutex> lock(mut);
// We use a while loop here because the monitor may have woken up because
// another producer did a PulseAll. In that case, the queue may not have
// room, so we need to re-check and re-wait if that is the case.
// We use an external stopwatch to stop the madness if we have taken too long.
while (queue.size() >= this->capacity)
{
int monitorTimeout = timeoutMillis - ((unsigned int) timer.getElapsedMilliSeconds());
if (monitorTimeout <= 0)
{
return false;
}
if (!cond.timed_wait(lock, boost::posix_time::milliseconds(timeoutMillis)))
{
return false;
}
}
cond.notify_all();
queue.push_back(myType);
return true;
}
void BlockingQueue::put(const MyType & myType)
{
// boost::unique_lock is a scoped lock - its destructor will call unlock().
// So no need for us to make that call here.
boost::unique_lock<boost::mutex> lock(mut);
// We use a while loop here because the monitor may have woken up because
// another producer did a PulseAll. In that case, the queue may not have
// room, so we need to re-check and re-wait if that is the case.
// We use an external stopwatch to stop the madness if we have taken too long.
while (queue.size() >= this->capacity)
{
cond.wait(lock);
}
cond.notify_all();
queue.push_back(myType);
}
MyType BlockingQueue::take()
{
// boost::unique_lock is a scoped lock - its destructor will call unlock().
// So no need for us to make that call here.
boost::unique_lock<boost::mutex> lock(mut);
while (queue.size() == 0)
{
cond.wait(lock);
}
cond.notify_one();
MyType myType = this->queue.front();
this->queue.pop_front();
return myType;
}
unsigned int BlockingQueue::getCapacity()
{
return this->capacity;
}
unsigned int BlockingQueue::getCount()
{
return this->queue.size();
}
是的,我沒有使用模板實現類 - 這是列表中的下: )
任何幫助,非常感謝。線程問題很難確定。
Ben
你可以請示*你如何使用這個課程?特別是您打電話給'take'。請嘗試製作一個[簡單的可編譯示例](http://sscce.org/),它將顯示此行爲。 –
你的「MyType」如何被複制?這是一個微不足道的POD結構嗎? –
它究竟在哪條線上拋出? –