시간 초과 가능 offer()
과 함께 C++의 블로킹 큐가 필요했습니다. 대기열은 인 복수의 생산자 을 대상으로합니다. 이전에 구현할 때이 필요에 맞는 기존의 대기열을 찾지 못해서 직접 코딩했습니다.C++ 블로킹 큐 Segfault 승격
대기열의 take()
메소드에서 나오는 segfaults가 표시되지만 간헐적 인 것입니다. 문제에 대한 코드를 살펴 봤지만 문제가있는 것으로 보이지 않습니다.
- 안정적으로이 작업을 수행 기존 라이브러리가 있다는 것을 내가해야 사용 (부스트 또는 헤더 전용 권장) :
나는 경우 궁금하네요.
- 누구나 수정해야 할 코드에 명백한 결함이있는 것 같습니다.
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
*이 수업을 어떻게 사용합니까? 특히 예를 들어 '가져 가라. ' 이 동작을 나타내는 [간단한 컴파일 가능한 예제] (http://sscce.org/)를 만들어보십시오. –
"MyType"은 어떻게 복사됩니까? 사소한 포드 구조체입니까? –
정확히 어떤 라인에서 던지나요? –