使用 asio 提升线程池:线程随机不执行
Posted
技术标签:
【中文标题】使用 asio 提升线程池:线程随机不执行【英文标题】:Boost threadpool using asio: Threads randomly don't execute 【发布时间】: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
【问题讨论】:
【参考方案1】:你打电话给io_service::run()
,但不要把any work给io_service
,所以run()
just exits。现在你必须在任何后续的run()
之前调用io_service::reset()
。
它有时会起作用的事实是由于竞争条件:ioService.post(boost::bind(doSomething, 40))
可能会在池中的线程启动之前的片刻在主线程中执行,从而给 io_service
一些工作。
【讨论】:
【参考方案2】:你应该读一遍,再读一遍,that post来自Tanner Sansbury,他是一个asio老板!
asio 没有那么复杂,但只有一次才能完全理解这个基本行为。
欢迎来到 asio 的精彩世界!
【讨论】:
以上是关于使用 asio 提升线程池:线程随机不执行的主要内容,如果未能解决你的问题,请参考以下文章