boost::thread производитель потребитель

Я новичок вboost::thread. Я создаю производителя-потребителя с монитором. Вот как я закодировал это до сих пор.

//{ Declarations in header
private:
  boost::condition_variable    _condition;
  boost::mutex                 _mutex;
  std::deque<RawMatrix*>       _queue;
  boost::detail::atomic_count  _count;
//}

void MatrixMonitor::deposit(RawMatrix* rawMatrix){
    boost::unique_lock<boost::mutex> lock(_mutex);
    _condition.wait(lock, boost::bind(std::less_equal<int>(), boost::ref(_count), max));
    _queue.push_back(rawMatrix);
    ++_count;
    _condition.notify_one();
}

RawMatrix* MatrixMonitor::withdraw(){
    boost::unique_lock<boost::mutex> lock(_mutex);
    _condition.wait(lock, boost::bind(std::greater_equal<int>(), boost::ref(_count), min));
    RawMatrix* elem = _queue.front();
    _queue.pop_front();
    --_count;
    _condition.notify_one();
    return elem;
}

Все хорошо ? и одна вещь, которую я не могу понять, это то, как мне теперь спроектировать производителя и потребителя? До сих пор я сделал

void MatrixProducer::produce(){
    boost::mutex::scoped_lock lock(_mutex);
    RawMatrix* matrix = rawMatrix();
    _monitor->deposit(matrix);
}
RawMatrix* MatrixProducer::rawMatrix(){/*Generates and returns a matrix*/}

Но как я могу/должен запускать produce() через какой-то интервал. и я не знаю, что мне нужно написать в потребительском. и кто будет владеть этим производителем, потребителем и монитором?


person Dipro Sen    schedule 27.07.2012    source источник


Ответы (1)


Все хорошо ?

  1. Вы не должны использовать одну переменную условия для двух разных предикатов. Используйте одну переменную условия для условия полной очереди и одну для условия пустой очереди, иначе вы получите пропущенные обновления.

  2. В вашей функции product() вы не должны блокировать второй мьютекс, если в этом нет необходимости. Если это необходимый предикат для вызова rawMatrix(), вы можете по крайней мере освободить мьютекс перед вызовом Deposit(), чтобы не блокировать два мьютекса. Каждый раз, когда вы блокируете более одного мьютекса, вы должны знать о возможных мертвых блокировках. Один из способов избежать взаимоблокировок — всегда блокировать мьютекс в одном и том же порядке (так называемая иерархия блокировок).

как бы я спроектировал производителя и потребителя сейчас?

Проектирование вашего производителя и потребителя зависит от вас и в значительной степени зависит от ваших требований. Схема производитель/потребитель используется для отделения производства рабочей нагрузки от фактической обработки. Это буфер для работы.

кто будет владеть этим производителем, потребителем и монитором?

В зависимости от вашего дизайна может иметь смысл, что производитель владеет очередью, а очередь владеет потребителями.

person Torsten Robitzki    schedule 31.07.2012
comment
Если я разблокирую мьютекс перед вызовом rawMatrix(), разве мне не нужно будет блокировать мьютекс внутри rawMatrix()? - person Dipro Sen; 01.08.2012
comment
Конечно, мьютекс внутри rawMatrix() предназначен для защиты _queue и _count от того, что другие потоки увидят их в несогласованном состоянии. - person Torsten Robitzki; 01.08.2012