在 C++11 中实现 future::then() 等价于异步执行
我对 then() 的实现有几个问题Beyond-2012-Herb-Sutter-Concurrency-and-Parallelism" rel="noreferrer">Herb Sutter 的演讲.此函数用于链接异步操作,参数 f
是一个操作的未来,参数 w
是此操作的工作"(lambda).>
I have a few questions about the implementation of the function then()
in Herb Sutter's talk. This function is used to chain asynchronous operations, the parameter f
is a future from one operation and the parameter w
is the 'work' for this operation (lambda).
template <typename Fut, typename Work>
auto then(Fut f, Work w) -> future<decltype(w(f.get()))>
{
return async([=]{ w(f.get()); });
}
应用示例如下:
std::future<int> f = std::async([]{
std::this_thread::sleep_for(std::chrono::microseconds(200));
return 10;
});
auto f2 = then(std::move(f), [](int i){
return 2 * i;
});
主线程产生任务,但不等待它们中的任何一个完成.
The main thread spawns the tasks but does not wait for any of them to finish.
首先,future
没有复制构造函数.这意味着,建议的实现只能与 shared_future
一起使用,除非我们更改对 async()
的调用以将未来移动到 lambda 中.这个问题提出了一种方法它但它似乎太复杂了.我重新实现了这个函数,我想知道我的代码是否正确或者我是否遗漏了什么......
Firstly, future<T>
does not have a copy constructor. This means, that the suggested implementation can be only used with shared_future<T>
unless we change the call to async()
to move the future into the lambda. This SO question suggested a way of doing it but it seems too complicated. I re-implemented the function and I am wondering whether my code is correct or whether I missed something...
其次,传递给 then()
函数的 future 可能是 void
所以我们实际上需要 then()
的 2 个实现, 对?一种用于返回 T
的期货,一种用于返回 void
的期货.
Secondly, the future that is passed to the then()
function might be void
so we actually need 2 implementations of then()
, right? One for futures returning T
and one for futures returning void
.
最后,then()
主体内的 lambda 是否应该没有 return 语句,以便我们可以实际返回值?没有return语句,则返回future
,对吗?
Lastly, should the lambda inside the body of then()
not have a return statement so that we can actually return the value back? Without the return statement, then returns future<void>
, right?
我试图解决以上几点,这就是我想出的.正确吗?
I tried to address the above points and this is what I came up with. Is it correct?
template <typename T, typename Work>
auto then(future<T> f, Work w) -> future<decltype(w(f.get()))>
{
return async([](future<T> f, Work w)
{ return w(f.get()); }, move(f), move(w));
}
template <typename Work>
auto then(future<void> f, Work w) -> future<decltype(w())>
{
return async([](future<void> f, Work w)
{ f.wait(); return w(); }, move(f), move(w));
}
推荐答案
这种 .then() 方法的问题在于,您同时生成 2 个线程(代价高昂),而其中的第二个线程会阻塞它的未来.获取/等待(当然,如果第一个运行时间足够长)因此,最好使用工作队列来序列化作业执行顺序(并回收现有线程).只需要寻找一个好的线程池模式实现
The problem with this approach to .then() is that you spawn 2 threads (that is costly) simultaneously, and second of them would block on its future.get/wait (if the first one would run long enough, of course) So, its better to use the work queue, to serialize the jobs execution order (and re-cycle the existing threads). Just look for a good Thread pool pattern implementation
相关文章