2013-10-21 11 views
38

मैं सी ++ में बढ़ावा का उपयोग करके थ्रेड पूल कैसे बना सकता हूं, और मैं थ्रेडपूल में कार्यों को कैसे निर्दिष्ट करूं?सी ++ में बढ़ावा का उपयोग करके थ्रेड पूल कैसे बनाएं?

+0

([एक धागा पूल बढ़ावा का उपयोग कर बनाया जा रहा है] के संभावित डुप्लिकेट 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

प्रक्रिया बहुत सरल है। पहले एएसओ :: io_service और थ्रेड_ग्रुप बनाएं। Thread_group को io_service से जुड़े थ्रेड के साथ भरें। 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) ऑब्जेक्ट एक महत्वपूर्ण टुकड़ा है इसे ठीक से काम करने के लिए। इसके अलावा ['io_service :: रोकें()'] (http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/io_service/stop.html) किसी भी अतिरिक्त कार्य को निष्पादित करने से रोक देगा, इस पर ध्यान दिए बिना कि कार्य को 'io_service' में पोस्ट किया गया है। उदाहरण के लिए, 'स्टॉप() 'से पहले' io_service' कतार में' getSocialUpdates() 'जोड़ा जाता है, यदि 'रोकें)' लागू होने पर मध्य-निष्पादन नहीं होता है, तो यह कतारबद्ध रहेगा। –

+2

* कार्यकर्ता धागे बनाने से पहले आपको 'कार्य' ऑब्जेक्ट * बनाना होगा, अन्यथा वे बिना कुछ किए बिना तुरंत समाप्त हो सकते हैं। – Miral

+6

@ टैनरसंसबरी असल में यह नुस्खा मुझे बहुत भ्रमित कर देता है, क्योंकि 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 आप कैसे जानते हैं मुझे नहीं पता कि पूछने वाले को कोड पसंद है? – squid

+20

आप मेरी टिप्पणी से कैसे पढ़ते हैं कि मुझे पता है कि आप नहीं जानते कि पूछने वाले को कोड पसंद है या नहीं? – x29a

संबंधित मुद्दे