FB Folly:期货,承诺和纤维

时间:2019-03-17 10:40:02

标签: multithreading fibers folly

Folly的Fibers为我们提供了Promise的特殊实现,并且Future已经对光纤友好。但是,这种特殊的Promise并没有为用户提供getFuture方法,至少在我看来,这种方法使Promise无法使用。问题是,“通用”愚蠢的Promise是否可以在纤维中起作用?

然后我整理了一个简单的测试以进行经验检验。

#include <chrono>
#include <iostream>

#include <gtest/gtest.h>
#include <gmock/gmock.h>

#include <folly/futures/Future.h>
#include <folly/fibers/AddTasks.h>
#include <folly/fibers/EventBaseLoopController.h>

namespace ff = folly::fibers;
using namespace std::chrono_literals;


TEST(FiberManager, addTasksNoncopyable)
{
    std::atomic_size_t counter = 0;
    folly::Promise<int> promise;
    auto future = promise.getSemiFuture();

    ff::FiberManager::Options opts;
    ff::FiberManager manager(std::make_unique<ff::EventBaseLoopController>(), opts);

    folly::EventBase evb;
    dynamic_cast<ff::EventBaseLoopController&>(manager.loopController()).attachEventBase(evb);

    manager.addTask([&]() {
        for (auto i = 0; i < 10; ++i) {
            ++counter;
            std::cout << counter << std::endl;
        }
    });
    manager.addTask([&, promise{std::move(promise)}]() mutable {
        folly::fibers::Baton sleepBaton;
        sleepBaton.try_wait_for(1s);
        promise.setValue(42);
    });
    manager.addTask([&, future{std::move(future)}]() mutable {
        auto res = std::move(future).get();
        EXPECT_EQ(res, 42);
        std::cout << res << std::endl;
    });
    manager.addTask([&]() {
        for (auto i = 0; i < 10; ++i) {
            folly::fibers::Baton sleepBaton;
            sleepBaton.try_wait_for(100ms);
            ++counter;
            std::cout << counter << std::endl;
        }
    });

    evb.loop();
    EXPECT_EQ(counter.load(), 20);
}

int main(int argc, char* argv[])
{
    ::testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}

给人的印象是,它像仿制药Promise在光纤中工作一样令人惊讶

0 个答案:

没有答案