покритикуйте! - имплементация boss-workers
От: Olksy Украина  
Дата: 19.05.11 16:35
Оценка:
Пожалуйста покритикуйте мою имплементацию самого самого распостраненного паттерна многопоточного программирования 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


И спасибо!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.