Пожалуйста покритикуйте мою имплементацию самого самого распостраненного паттерна многопоточного программирования Boss Worker!
Что интересует: концептульные просчёты, ненужные плюшки и есть ли аналогичкая имплементация в майнстримных библиотеках С++? Т.к., например, оный паттерн становиться ненужен с С#, там можно оч. удобно закодить через PLINQ
#include <boost/bind.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/thread.hpp>
namespace util {
template<class QueueItemType, class ProductType>
struct Worker
{
virtual ProductType proceed(QueueItemType) = 0;
virtual ~Worker() {}
};
template<class QueueItemType,
class ProductType,
class WorkerIterator,
class QueueItemIterator,
class ProductOutputIterator
>
/**
* The Boss is motivating workers to act in parallel
*/
class Boss
{
typedef Worker<QueueItemType, ProductType> TheWorker;
WorkerIterator workersBegin_;
WorkerIterator workersEnd_;
QueueItemIterator queueBegin_;
QueueItemIterator queueEnd_;
ProductOutputIterator productOutputIterator_;
public:
Boss(WorkerIterator workersBegin,
WorkerIterator workersEnd,
QueueItemIterator queueBegin,
QueueItemIterator queueEnd,
ProductOutputIterator productOutputIterator)
: workersBegin_(workersBegin)
, workersEnd_(workersEnd)
, queueBegin_(queueBegin)
, queueEnd_(queueEnd)
, productOutputIterator_(productOutputIterator)
{
}
void getThingsDone()
{
if( workersBegin_ == workersEnd_ )
return; // as the input is, such is the output :)
boost::thread_group threads;
for(WorkerIterator workerIt = workersBegin_; workerIt != workersEnd_; ++workerIt)
{
TheWorker &worker = *workerIt;
threads.create_thread( boost::bind(&Boss::loadWorker, this, boost::ref(worker)) );
}
threads.join_all();
}
private:
boost::mutex popQueueItemMutex_;
boost::mutex collectProductMutex_;
void loadWorker(TheWorker& worker)
{
while(QueueItemType *item = popQueueItem())
{
ProductType product = worker.proceed(*item);
collectProduct( product );
}
}
/**
* Thread-safe dequeue
*
* @return null if the end of queue
*/
QueueItemType* popQueueItem()
{
boost::mutex::scoped_lock scopedLock(popQueueItemMutex_);
if (queueBegin_ == queueEnd_)
return NULL;
else
return &* (queueBegin_++);
}
/**
* Thread-safe product collect
*/
void collectProduct(ProductType product)
{
boost::mutex::scoped_lock scopedLock(collectProductMutex_);
*(productOutputIterator_++) = product;
}
}; // class Boss
} // namespace util
И спасибо!