2013-12-17 102 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的美妙世界!