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 源码之美》系列文章的目录,希望你能在这个列表里找到自己感兴趣的内容。