2013-12-17 98 views
1

我正在使用基於boost::asio::ioService的線程池。但是,線程有時不會執行發佈到ioService的工作。使用asio提升線程池:線程隨機不執行

我建立以下幾個最基本的例子來研究這個:

#include <boost/thread.hpp> 
#include <boost/asio.hpp> 
#include <iostream> 

#include "threadpool.h" 

int fib(int x) { 
    if (x == 0) return 0; 
    if (x == 1) return 1; 
    return fib(x-1)+fib(x-2); 
} 

void doSomething(int value) 
{ 
    std::cout << "doSomething(): " << fib(value) << std::endl; 
} 

void doSomethingElse(int value) 
{ 
    std::cout << "doSomethingElse(): " << value+value << std::endl; 
} 

int main(int argc, char** argv) 
{ 
    // create asio ioservice and threadgroup for the pool 
    boost::asio::io_service ioService; 
    boost::thread_group threadpool; 

    // Add worker threads to threadpool 
    for(int i = 0; i < 5; ++i) 
    { 
    threadpool.create_thread(
     boost::bind(&boost::asio::io_service::run, &ioService)); 
    } 

    // post work to the ioservice 
    ioService.post(boost::bind(doSomething, 40)); 
    ioService.post(boost::bind(doSomethingElse, 3)); 

    // run the tasks and return, if all queued work is finished 
    ioService.run(); 

    // join all threads of the group 
    threadpool.join_all(); 
} 

如果我跑這在一個循環中,像這樣:

while true; do echo "--------------"; ./boost_threadpool_test; done 

我會得到類似的輸出:

-------------- 
doSomething(): 102334155 
doSomethingElse(): 6 
-------------- 
-------------- 
-------------- 
-------------- 
doSomething(): 102334155 
doSomethingElse(): 6 
-------------- 
-------------- 
-------------- 
doSomething(): 102334155 
doSomethingElse(): 6 
-------------- 
-------------- 
doSomething(): 102334155 
doSomethingElse(): 6 
-------------- 
-------------- 
-------------- 
-------------- 
-------------- 
-------------- 
doSomething(): 102334155 
doSomethingElse(): 6 
-------------- 

因此2個或更多個連續的行顯示線程沒有處理他們的工作。 我也試過我自己的一個線程池的實現,只是使用boost線程組來切出IOService,但有類似的結果。 這裏有一些基本的東西我錯了嗎?

BTW:我在升壓1.46.1

回答

4

你叫io_service::run(),但不給any workio_service,所以run()just exits。現在,您必須在隨後的run()之前撥打io_service::reset()

它有效的事實有時是由於競爭條件:ioService.post(boost::bind(doSomething, 40))可能會在池中的線​​程開始之前的一段時間在主線程中執行,因此給io_service一些工作。

+0

謝謝。這使我朝着正確的方向前進。 – GeeF

1

你應該讀,再讀,that postTanner Sansbury,他是一個ASIO老闆!

asio不是那麼複雜,但只有一次,這種基本的行爲是完全理解。

歡迎在asio的美妙世界!