我已经浏览了Stack Overflow并且已经有了一些非常好的答案,(我的代码实际上基于this answer here)但是由于某种原因我得到了奇怪的行为 - 因为应该调用thread_func ls1次,但它只在线程退出之前运行0到2次。看起来ioService.stop()在完成排队的作业之前会切断排队的作业,但据我所知,这不应该发生。以下是相关的代码段:
boost::asio::io_service ioService;
boost::asio::io_service::work work(ioService);
boost::thread_group threadpool;
for (unsigned t = 0; t < num_threads; t++)
{
threadpool.create_thread(boost::bind(&boost::asio::io_service::run, &ioService));
}
//Iterate over the dimensions of the matrices
for (unsigned i = 0; i < ls1; i++)
{
ioService.post(boost::bind(&thread_func,i, rs1, rs2, ls2, arr, left_arr, &result));
}
ioService.stop();
threadpool.join_all();
非常感谢任何帮助,谢谢!
答案 0 :(得分:5)
io_service::stop()
会导致run()
或run_one()
的所有调用尽快返回。它不会删除已排队到io_service
的任何未完成的处理程序。调用io_service::stop()
时,threadpool
中的线程将尽快返回,从而导致每个执行线程完成。
由于io_service::post()
将在请求io_service
调用处理程序后立即返回,因此threadpool
中io_service
之前的线程将调用多少个已发布的处理程序是不确定的。 {1}}已停止。
如果您希望thread_func
被调用ls1
次,那么一个简单的替代方法是重新组织代码,以便在io_service
之前将工作添加到threadpool
为它提供服务,然后应用程序让io_service
运行完成。
boost::asio::io_service ioService;
// Add work to ioService.
for (unsigned i = 0; i < ls1; i++)
{
ioService.post(boost::bind(
&thread_func,i, rs1, rs2, ls2, arr, left_arr, &result));
}
// Now that the ioService has work, use a pool of threads to service it.
boost::thread_group threadpool;
for (unsigned t = 0; t < num_threads; t++)
{
threadpool.create_thread(boost::bind(
&boost::asio::io_service::run, &ioService));
}
// Once all work has been completed (thread_func invoked ls1 times), the
// threads in the threadpool will be completed and can be joined.
threadpool.join_all();
答案 1 :(得分:1)
如果您希望thread_func
被调用ls1
次,那么您应该等到实际调用ls1
次,然后再停止io_service。如上所述,在任何线程都有机会被安排之前,可以调用stop()
。
有很多方法可以等待这种情况。例如,您可以使用条件变量:
#include <boost/asio.hpp>
#include <boost/thread.hpp>
unsigned num_threads = 10, ls1=11;
int result = 0;
boost::mutex m;
boost::condition_variable cv;
void thread_func(unsigned , int* result) {
/* do stuff */
{
boost::lock_guard<boost::mutex> lk(m);
++*result;
}
cv.notify_one();
}
int main()
{
boost::asio::io_service ioService;
boost::asio::io_service::work work(ioService);
boost::thread_group threadpool;
for (unsigned t = 0; t < num_threads; t++)
threadpool.create_thread(boost::bind(&boost::asio::io_service::run,
&ioService));
for (unsigned i = 0; i < ls1; i++)
ioService.post(boost::bind(&thread_func,i,&result));
{
boost::unique_lock<boost::mutex> lk(m);
cv.wait(lk, []{return result == ls1; });
}
ioService.stop();
threadpool.join_all();
std::cout << "result = " << result << '\n';
}