这是我的问题,可以说我有一大堆需要同步执行的同步代码,而我有一个线程池。我可以为此“任务”提供标注,该标注可以为Boost Promise设置值。
现在我等待一个调度程序线程以io_service的身份运行,该服务将通过io.post获得“请求”,从池中选择一个工作线程,将作业提交给它,然后传递“标注”(在工作线程上运行并“执行” promise.set_value”。 我想发生的是某种将在“ io_service”上执行的“继续”。 我可以做到的一种方法是,“标注”将在io_service上提交“新作业”,该作业可以是从“请求启动器”传递的lambda,因此不使用“承诺”和“未来”。 问题是我可以以某种方式使用“未来”吗?以某种方式使“ promise.set_value”提交此“延续”。
我尝试了以下代码,如下所示:
void worker(promise<int>& p) {
sleep(10);
p.set_value(10);
}
int main(int argc, char **argv) {
io_service io;
io_service::work work(io);
promise<int> p;
io.post([&] {
std::cout << "submission id:" << boost::this_thread::get_id() << std::endl;
boost::thread my_thread(&worker, boost::ref(p));
p.get_future().then(launch::async, [](future<int> p){
std::cout << "completion thread id:" << boost::this_thread::get_id() << std::endl;
});
});
io.run();
}
这是输出: 职位编号:7f0c7b825b80 工作完成编号:7f0c798be700
似乎它正在不同的线程上运行完成,并且我需要在“ io_service”上调用它..我应该从侧线程“发布”新的“ JOB”吗?
我使用的是1.65助推器。
答案 0 :(得分:0)
您可能想看看boost.future:
boost::future
优于std::future
,因为您可以使用.then([executor], continuation_function)
将延续延续到未来。
在最新版本的asio中,io_context::executor_type
(来自.get_executor()
)和io_context::strand
为执行者建模。
答案 1 :(得分:0)
基本上,当一个函数提供结果时,您想同步post
附加代码。使用promise
进行同步通信是多余的(请记住promise
使用同步对象)。
绕过post
,您最初的想法是io_service
延续到promise
,是一个更好的主意:
int worker() {
this_thread::sleep_for(2s);
return 10;
}
int main(int argc, char **argv) {
io_service io;
io_service::work work(io);
thread my_thread; // assuming this represents the thread pool
io.post([&] {
std::cout << "submission id:" << this_thread::get_id() << std::endl;
my_thread = thread([&io] { // assuming this represents posting a task to the pool
auto result = worker();
io.post([&io, result] {
std::cout << "completion thread id:" << this_thread::get_id()
<< ", result:" << result << std::endl;
});
});
});
io.run();
}
注意。另一个答案的想法是这样的:
p.get_future().then(io.get_executor(), [](future<int> p) {
std::cout << "completion thread id:" << boost::this_thread::get_id() << std::endl;
});
它对您不起作用,因为io_context::executor_type
和future.then([Executor&],...)
在Boost 1.66中可用(由于ASIO执行程序中缺少try_executing_one()
,它仍然可能不起作用)。 / p>