仅当使用c ++中的boost完成所有任务时,如何将新任务添加到线程池

时间:2015-04-02 14:28:35

标签: c++ multithreading boost threadpool boost-asio

boost::asio::io_service ioService;
boost::thread_group threadpool;
boost::barrier barrier(5);
boost::asio::io_service::work work(ioService);
threadpool.create_thread(boost::bind(&boost::asio::io_service::run, &ioService));  //Thread 1
threadpool.create_thread(boost::bind(&boost::asio::io_service::run, &ioService));  //Thread 2
threadpool.create_thread(boost::bind(&boost::asio::io_service::run, &ioService));  //Thread 3 threadpool.create_thread(boost::bind(&boost::asio::io_service::run, &ioService));  //Thread 4

while (true)
{
  { 
     boost::lock_guard<boost::recursive_mutex> lock(mutex_);
     map::iterator it = m_map.begin();   
     while (it != m_map.end())
     {
         ioService.post(boost::bind(&ProcessFun, this, it));
         ++it;    
     }

    ioService.run(); <-- main thread is stuck here..  
   }

}

我希望能够知道分配给线程池的所有任务都已完成,只有在将任务再次分配给线程池之后才能完成。

只要线程处理任务,我就不想释放锁。 有什么办法可以确保完成所有分配的任务吗?然后才继续?

2 个答案:

答案 0 :(得分:2)

最简单的方法是调用ioService.run()根据boost asio文档:

  

io_service对象的run()函数在工作时不会退出   进行。当没有未完成的工作时它会退出   其余

顺便说一句,如果没有看到更多的程序,很难确定这一点,但看起来你试图打败asio的主要目的。您正在序列化批量任务。如果批量#1中的所有任务在批处理#2中的任何任务开始之前完全处理是很重要的话,那么这可能是有意义的,但这是一个奇怪的用法。

另外要注意,如果批处理#1任务的任何处理程序尝试添加新任务,它们可能会死锁,尝试获取互斥锁上的锁。

答案 1 :(得分:0)

所以,我的最终解决方案是创建一个我自己的小信号量,其中mutex和条件值得信赖 我在这里找到了:

C++0x has no semaphores? How to synchronize threads?

我将此信号量作为指向线程的指针传递,并在每次迭代时重置它。 我不得不修改一下信号量代码以启用重置功能,因为我的线程有时在主线程进入睡眠之前完成工作我必须修改abit中的条件

class semaphore
{
private:
    boost::mutex mutex_;
    boost::condition_variable condition_;
    unsigned long count_;

public:
    semaphore()
        : count_()
    {}

    void reset(int x)
    {
      count = x;
    }
    void notify()
    {
        boost::mutex::scoped_lock lock(mutex_);
        ++count_;
        if(count_ < 1)
            condition_.notify_one();
    }

    void wait()
    {
        boost::mutex::scoped_lock lock(mutex_);
        while(count_ > 1)
            condition_.wait(lock);

    }
};


....
....
semaphore*  m_semaphore = new semaphore();

while (true)
{
  { 
     boost::lock_guard<boost::recursive_mutex> lock(mutex_);
     map::iterator it = m_map.begin();
     if(it ! = m_map.end())
        m_semaphore->reset(m_map.size());  
     while (it != m_map.end())
     {
         ioService.post(boost::bind(&ProcessFun, this, it, &m_semaphore));
         ++it;    
     }

      m_semaphore.wait();
   }

}
相关问题