何时使用过异步​​或packaged_task承诺? [英] When to use promise over async or packaged_task?

查看:176
本文介绍了何时使用过异步​​或packaged_task承诺?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我应该使用的std ::承诺的std ::异步 STD :: packaged_task
你能给我什么时候使用他们中的每一个实际的例子吗?

When should I use std::promise over std::async or std::packaged_task? Can you give me practical examples of when to use each one of them?

推荐答案

的std ::异步 是一个整洁和简单的方法来得到一个 的std ::未来 ,但是:

std::async

std::async is a neat and easy way to get a std::future, but:


  • 不总是启动一个新的线程;通过的std ::推出::异步作为第一个参数,迫使它。

  • Not always it starts a new thread; pass std::launch::async as a first parameter to force it.

auto f = std::async( std::launch::async, func );


  • 的std ::〜未来的析构函数的可以的块,直到新线程完成

  • the std::~future destructor can block until new thread finishes

    auto sleep = [](int s) { std::this_thread::sleep_for(std::chrono::seconds(s)); };
    
    {
        auto f = std::async( std::launch::async, sleep, 5 );
    }
    

    通常情况下,我们预计,仅获得() .wait()块,但为的std ::未来的std ::异步的析构函数也可能会阻止,所以要小心,不要只是忘记阻止你的主线程一下吧。

    Normally we expect that only .get() or .wait() blocks, but for std::future returned from std::async destructor also may block, so be careful not to block your main thread just by forgetting about it.

    如果在的std ::未来存储在一个临时的生活目标,的std ::异步调用将阻塞现货,所以下面块将采取的如果您删除自动F = 初始化:

    if the std::future is stored in a temporary-life object, std::async call will block on spot, so the following block will take 10 seconds if you remove the auto f = initializations:

    auto sleep = [](int s) { std::this_thread::sleep_for(std::chrono::seconds(s)); };
    
    {
        auto f1 = std::async( std::launch::async, sleep, 5 );
        auto f2 = std::async( std::launch::async, sleep, 5 );
    }
    


  • 的std :: packaged_task 本身无关,与线程:它只是一个仿函数和相关的未来。考虑以下几点:

    std::packaged_task by itself has nothing to do with threads: it is just a functor and a related future. Consider the following:

    auto task = [](int i) { std::this_thread::sleep_for(std::chrono::seconds(5)); return i+100; };
    
    std::packaged_task< int(int) > package{ task };
    std::future<int> f = package.get_future();
    package(1);
    std::cout << f.get() << "\n";
    

    在这里,我们只需要运行由任务包(1),并返回后,˚F已就绪所以没有阻塞获得()

    Here we just run the task by package(1), and after it returns f is ready so no blocking on .get().

    不过:一个特点使packaged_task线程非常有用的。相反,只是一个功能,你可以初始化的std ::线程用packaged_task。考虑以下 - packaged_task是获得未来的一个非常好的方式:

    But: one feature make the packaged_task very useful for threads. Instead of just a function you can initialize std::thread with a packaged_task. Consider the following - packaged_task is a really nice way of getting future:

    std::packaged_task< int(int) > package{ task };
    std::future<int> f = package.get_future();
    std::thread t { std::move(package), 5 };
    
    std::cout << f.get() << "\n";       //block here until t finishes
    
    t.join();
    

    的std :: packaged_task 是不可拷贝,所以你将其与的std ::移动移动到新的任务。

    std::packaged_task is not copyable, so you move it to new task with std::move.

    的std ::承诺 是一个强有力的机制,例如,你可以将值传递给新的线程,而无需任何额外的同步机制。

    std::promise is a powerful mechanism, for example you can pass a value to new thread without need of any additional synchronizing mechanism.

    auto task = [](std::future<int> i) {
        std::cout << i.get() << std::flush;
    };
    
    std::promise<int> p;
    std::thread t{ task, p.get_future() };
    
    std::this_thread::sleep_for(std::chrono::seconds(5));
    p.set_value(5);
    
    t.join();
    

    新的线程将等待我们获得()

    所以,总的来说,回答你的问题:

    So, in general, answering your question:


    • 使用的std ::异步只是简单的东西,比如要在心中有些通话无阻塞,但熊上面挡住了意见。

    • 使用的std :: packaged_task 来轻松搞定未来,并运行它作为一个单独的线程

    • use std::async only to simple things, for example to make some call non-blocking, but bear in mind the comments on blocking above.
    • use std::packaged_task to easily get future, and run it as a separate thread

    std::thread{ std::move(package), param }.detach();
    

    std::thread t { std::move(package), param };
    


  • 使用的std ::承诺当你需要在未来更多的控制权。

  • use std::promise when you need more control over the future.

    另请参阅 的std :: shared_future 并在线程之间传递异常<一个href=\"http://en.cp$p$pference.com/w/cpp/thread/promise/set_exception\"><$c$c>std::promise::set_exception

    这篇关于何时使用过异步​​或packaged_task承诺?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆