【问题标题】:Boost threadpool using asio: Threads randomly don't execute使用 asio 提升线程池:线程随机不执行
【发布时间】:2013-12-17 12:54:09
【问题描述】:

我正在使用基于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 线程组来切断 IOService,但结果相似。 我在这里有什么基本的错误吗?

顺便说一句:我正在使用 Boost 1.46.1

【问题讨论】:

    标签: c++ multithreading boost boost-asio


    【解决方案1】:

    你打电话给io_service::run(),但不要把any workio_service,所以run()just exits。现在你必须在任何后续的run() 之前调用io_service::reset()

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

    【讨论】:

      【解决方案2】:

      你应该读一遍,再读一遍,that post来自Tanner Sansbury,他是一个asio老板!

      asio 没有那么复杂,但只有一次才能完全理解这个基本行为。

      欢迎来到 asio 的精彩世界!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-08-26
        • 2011-12-18
        相关资源
        最近更新 更多