簡體   English   中英

使用Boost線程和io_service創建線程池

[英]Using Boost threads and io_service to create a threadpool

我環顧了Stack Overflow,對此有一些非常好的答案,(我的代碼實際上基於這里的答案 ),但是由於某種原因,我的行為越來越怪異-在thread_func中應該調用ls1次,但是在線程退出之前僅運行0到2次。 似乎ioService.stop()在完成排隊的作業之前就將其切斷,但是據我了解,這不應該發生。 這是相關的代碼片段:

boost::asio::io_service ioService;
boost::asio::io_service::work work(ioService);

boost::thread_group threadpool;

for (unsigned t = 0; t < num_threads; t++)
{   
    threadpool.create_thread(boost::bind(&boost::asio::io_service::run, &ioService));
}   

//Iterate over the dimensions of the matrices
for (unsigned i = 0; i < ls1; i++)
{   
    ioService.post(boost::bind(&thread_func,i, rs1, rs2, ls2, arr, left_arr, &result));
}   

ioService.stop();
threadpool.join_all();

任何幫助將不勝感激,謝謝!

io_service::stop()導致run()run_one()所有調用盡快返回。 它不會刪除已排隊到io_service中的任何未完成的處理程序。 調用io_service::stop() ,線程threadpool的線程將盡快返回,從而使每個執行線程均完成。

由於io_service::post()將在請求io_service調用處理程序后立即返回,因此,在io_service停止之前,線程threadpool的線程將調用多少已發布的處理程序是不確定的。

如果您希望thread_func被調用ls1次,那么一個簡單的辦法是重新組織代碼,使工作被添加到io_service的前threadpool服務,然后該應用程序讓io_service運行完成。

boost::asio::io_service ioService;

// Add work to ioService.
for (unsigned i = 0; i < ls1; i++)
{   
  ioService.post(boost::bind(
      &thread_func,i, rs1, rs2, ls2, arr, left_arr, &result));
}   

// Now that the ioService has work, use a pool of threads to service it.
boost::thread_group threadpool;    
for (unsigned t = 0; t < num_threads; t++)
{   
  threadpool.create_thread(boost::bind(
      &boost::asio::io_service::run, &ioService));
}   

// Once all work has been completed (thread_func invoked ls1 times), the
// threads in the threadpool will be completed and can be joined.
threadpool.join_all();

如果您希望thread_func被調用ls1次,那么您應該等到它實際被調用ls1次之后再停止io_service。 如所寫,在任何線程有機會被調度之前,可以調用stop()

有很多方法可以等待這種情況。 例如,您可以使用條件變量:

#include <boost/asio.hpp>
#include <boost/thread.hpp>
unsigned num_threads = 10, ls1=11;
int result = 0;
boost::mutex m;
boost::condition_variable cv;
void thread_func(unsigned , int* result) {
    /* do stuff */
    {
        boost::lock_guard<boost::mutex> lk(m);
        ++*result;
    }
    cv.notify_one();
}
int main()
{
    boost::asio::io_service ioService;
    boost::asio::io_service::work work(ioService);
    boost::thread_group threadpool;
    for (unsigned t = 0; t < num_threads; t++)
        threadpool.create_thread(boost::bind(&boost::asio::io_service::run,
                                             &ioService));
    for (unsigned i = 0; i < ls1; i++)
        ioService.post(boost::bind(&thread_func,i,&result));

    {
        boost::unique_lock<boost::mutex> lk(m);
        cv.wait(lk, []{return result == ls1; });
    }
    ioService.stop();
    threadpool.join_all();
    std::cout << "result = " << result << '\n';
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM