使用asio增加线程池:线程随机不执行

时间:2013-12-17 12:54:09

标签: c++ multithreading boost boost-asio

我正在使用基于boost::asio::ioService的线程池。但是,线程有时不会执行发布到ioService的工作。

我构建了以下最小的示例来调查此事:

#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 threadgroup来切断IOService,但结果相似。 我有什么基本的错误吗?

BTW:我正在升级1.46.1

2 个答案:

答案 0 :(得分:4)

您致电io_service::run(),但未向io_service提供any work,因此run() just exits。现在,您必须在任何后续io_service::reset()之前致电run()

它有时会起作用的事实是由于竞争条件:ioService.post(boost::bind(doSomething, 40))可能会在池中的线​​程开始之前的主线程中执行,从而使io_service一些工作

答案 1 :(得分:1)

您应该阅读that post来自Tanner Sansbury的{{3}},他是asio老板!

asio不是那么复杂,但只有一次完全理解了这个基本行为。

欢迎来到asio精彩的世界!