2013-10-21 21 views
38

C++'da destek kullanarak bir iş parçacığı havuzu nasıl oluşturur ve görevleri iş parçacığına nasıl atayabilirim?C++'da destek kullanarak iş parçacığı havuzu nasıl oluşturulur?

+0

([boost kullanılarak bir iş parçacığı havuzu oluşturma] olası yinelenen http://stackoverflow.com/ sorular/4084777/oluşturma-bir-havuz-kullanarak-boost) –

+0

Sadece bir şey, diğer soruya cevap vermeme izin vermez ve kendi kendine cevap verilir ve teşvik edilir. –

+0

[Diğer soru] için bir yanıt gönderebilmeniz gerekir (http://stackoverflow.com/questions/4084777/creating-a-thread-pool-using-boost), kapalı değil veya [korumalı] (http://meta.stackexchange.com/questions/52764/what-is-a-protected-question). –

cevap

59

İşlem oldukça basit. Önce bir asio :: io_service ve thread_group oluşturun. Thread_group io_service'ye bağlanmış iş parçacıkları ile doldurun. boost::bind işlevini kullanarak iş parçacıklarına görev atayın.

İpliklerini durdurmak için (genellikle programınızdan çıkarken) io_service'i durdurun ve tüm konulara katılın.

yalnızca bu başlıklara gerek olmalıdır: Burada

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

bir örnek:

/* 
* 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(); 

Kaynak: 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) nesnesi kritik bir parçadır Bunu düzgün çalışması için Ayrıca ['io_service :: stop()'] (http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/io_service/stop.html) herhangi bir ek görevin yürütülmesini engelleyecektir. Görevin io_service'de ne zaman yayınlandığına bakılmaksızın. Örneğin, getSocialUpdates(), 'stop()' dan önce "io_service" kuyruğuna eklenirken, stop() işlevi çağrıldığında orta yürütme değilse, sıraya girer. –

+2

"work" nesnesini * oluşturmanız gerekir * önce iş parçacığı oluşturursunuz, aksi takdirde bir şey yapmadan hemen sonlandırılabilirler. – Miral

+6

@TannerSansbury Aslında bu reçete beni çok kafa karıştırıcı yapıyor, çünkü io_service.stop() 'dan sonra tüm bitmemiş işlerim öldürülüyor. Uygun bir yol ioservice.stop() öğesini kaldırmalı, ancak iş nesnesini yok etmeli, sonra tüm işlerin bitmesini sağlamak için threadpool.join_all() öğesini çağırın. – CyberSnoopy

10

Sana kodu sevdiğini biliyorum. Kanunun

Benim Versiyon

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 
    }; 
} 

Piece Kullanılır:

{ 
    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

Üzgünüz, sadece sormak istediğim, askerin koddan hoşlandığını nereden biliyorsunuz? – x29a

+11

@ x29a Öykünün koddan hoşlandığını bilmediğimi nereden biliyorsunuz? – squid

+20

Yorumdan okuduğumda, testçinin koddan hoşlanıp haberi olmadığını bildiğinizi biliyorum. – x29a

İlgili konular