1 什么是 ready_future
如果一个 future 在当下就已经有结果了,不必等到未来某个时刻,
我们把这个 future 称为 ready_future。
ready_future 的不同之处在于:
(1) ready_future 可以单独使用,不必关联一个promise;
(2) ready_future.then(lambda) 会把传入的lambda立即执行掉,
也就是说这个lambda没有机会放入任务队列;
(3) 而not_ready_future每次执行,产生的新任务都会被放入任务队列,然后依此取出来执行。
2 ready_future 的执行
ready_future 会依此执行,每一个then都会返回一个新的future:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
void run(){
ready_future<int> fut{"v0"};
fut.then([](int x) {
ready_future<int> retfut{"task1"};
retfut.show();
return retfut;
}).then([](int x){
ready_future<int> retfut{"task2"};
retfut.show();
return retfut;
}).then([](int x){
ready_future<int> retfut{"task3"};
retfut.show();
return retfut;
}).then([](int x){
std::cout<< "last: " << x << std::endl;
});
}
|
3 not_ready_future 的执行
我们可以定义一个promise, 调用pr.get_future()获得的 future 就是 not ready的;
当这个 future调用 then() 时,会生成一个lambda_task, 存放到 promise 的一个成员上,
一旦promise.set_value(), 就将promise成员上的lambda_task放入任务队列排队,等待被执行。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
future<> test_not_ready_future() {
promise<> pr;
//此时的f是rescue返回的,其中finally和then返回的future对象,在当前函数返回时全部析构
auto f = pr.get_future().finally([=] {
OK();
throw std::runtime_error("");
}).then([] {
BUG();
}).rescue([] (auto get) {
OK();
});
// pr.set_value() 会把链表的第一个任务放入任务队列;
// 然后,这个pr对象也完成了它的使命,当前函数退栈时析构(RAII机制)
pr.set_value();
return f;
}
|
这种情况下,一个任务链表的任务严格保证序关系,但是不一定是连续的,中间可能有其他任务;
但是 ready_future 一条任务链保证是连续执行的(不进入任务队列,直接在then里面就被执行了)。
《全文完》
文末尾给出了《Seastar 源码之美》系列文章的目录,希望你能在这个列表里找到自己感兴趣的内容。