2013-10-21 76 views
38

如何在C++中使用boost来创建线程池,以及如何将任务分配给线程池?如何在C++中使用boost来创建线程池?

+0

[创建使用boost线程池(可能重复http://stackoverflow.com/问题/ 4084777 /创建线程池使用提升) –

+0

唯一的事情是它不允许我回答其他问题,并允许和鼓励自我回答。 –

+0

你应该能够发布[其他问题]的答案(http://stackoverflow.com/questions/4084777/creating-a-thread-pool-using-boost),它不是关闭或[保护] (http://meta.stackexchange.com/questions/52764/what-is-a-protected-question)。 –

回答

59

该过程非常简单。首先创建一个asio :: io_service和一个thread_group。使用链接到io_service的线程填充thread_group。使用boost::bind函数将任务分配给线程。

要停止线程(通常在退出程序时),停止io_service并加入所有线程。

你应该只需要这些标题:

#include <boost/asio/io_service.hpp> 
#include <boost/bind.hpp> 
#include <boost/thread/thread.hpp> 

这里有一个例子:

/* 
* Create an asio::io_service and a thread_group (through pool in essence) 
*/ 
boost::asio::io_service ioService; 
boost::thread_group threadpool; 


/* 
* This will start the ioService processing loop. All tasks 
* assigned with ioService.post() will start executing. 
*/ 
boost::asio::io_service::work work(ioService); 

/* 
* This will add 2 threads to the thread pool. (You could just put it in a for loop) 
*/ 
threadpool.create_thread(
    boost::bind(&boost::asio::io_service::run, &ioService) 
); 
threadpool.create_thread(
    boost::bind(&boost::asio::io_service::run, &ioService) 
); 

/* 
* This will assign tasks to the thread pool. 
* More about boost::bind: "http://www.boost.org/doc/libs/1_54_0/libs/bind/bind.html#with_functions" 
*/ 
ioService.post(boost::bind(myTask, "Hello World!")); 
ioService.post(boost::bind(clearCache, "./cache")); 
ioService.post(boost::bind(getSocialUpdates, "twitter,gmail,facebook,tumblr,reddit")); 

/* 
* This will stop the ioService processing loop. Any tasks 
* you add behind this point will not execute. 
*/ 
ioService.stop(); 

/* 
* Will wait till all the threads in the thread pool are finished with 
* their assigned tasks and 'join' them. Just assume the threads inside 
* the threadpool will be destroyed by this method. 
*/ 
threadpool.join_all(); 

来源:Recipes < Asio

+12

['boost :: asio :: io_service :: work'](http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/io_service__work.html)object is a critical piece使其正常运作。另外['io_service :: stop()'](http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/io_service/stop.html)将阻止执行任何其他任务,而不管任务何时发布到'io_service'中。例如,'getSocialUpdates()'在'stop()'之前被添加到'io_service'队列中,如果调用'stop()'时不是中等执行,那么它将保持排队。 –

+2

您需要在创建工作线程之前创建'work'对象*,否则它们可能会立即终止而无需执行任何操作。 – Miral

+6

@TannerSansbury其实这个配方让我非常困惑,因为在io_service.stop()之后,所有未完成的工作都会被杀死。正确的方法应该是除去ioservice.stop(),但是破坏工作对象,然后调用threadpool.join_all()让所有作业完成。 – CyberSnoopy

10

我知道你喜欢的代码。

我的版本

namespace bamthread 
{ 
    typedef std::unique_ptr<boost::asio::io_service::work> asio_worker; 

    struct ThreadPool { 
     ThreadPool(size_t threads) :service(), working(new asio_worker::element_type(service)) { 
      while(threads--) 
      { 
       auto worker = boost::bind(&boost::asio::io_service::run, &(this->service)); 
       g.add_thread(new boost::thread(worker)); 
      } 
     } 

     template<class F> 
      void enqueue(F f){ 
       service.post(f); 
      } 

     ~ThreadPool() { 
      working.reset(); //allow run() to exit 
      g.join_all(); 
      service.stop(); 
     } 

     private: 
     boost::asio::io_service service; //< the io_service we are wrapping 
     asio_worker working; 
     boost::thread_group g; //< need to keep track of threads so we can join them 
    }; 
} 

代码至少要使用它:

{ 
    bamthread::ThreadPool tp(n_threads); 
    BOOST_FOREACH(int y, boost::irange(starty, endy, step)){ 
     int im_x = 0; 
     BOOST_FOREACH(int x, boost::irange(startx, endx, step)){ 
      tp.enqueue (boost::bind(&camera_view_depth::threaded_intersection, this, 
         intersections, 
         intersected, 
         im_x, 
         im_y, 
         _faces, x, y)); 
      ++im_x; 
     } 
     ++im_y; 
    } 
} 
+17

对不起,我只是问,你怎么知道提问者喜欢的代码? – x29a

+11

@ x29a你怎么知道我不知道asker喜欢的代码? – squid

+20

你如何从我的评论中读到我知道你不知道提问者是否喜欢代码? – x29a