本文介绍了将std :: async替换为自己的版本,但是std :: promise应该在哪里?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用vc2011,结果是std :: async(std :: launch :: async,...)是一个有点儿bug(有时它不产生新的线程并运行它们并行,而是重用线程并一个接一个地运行任务)。这是太慢,当我做昂贵的网络电话。所以我想我会写我自己的异步函数。我遇到了困难,在哪里应std :: promise活?在1)线程函数,2)异步函数或3)调用函数。

I'm using vc2011 and it turns out the std::async(std::launch::async, ... ) is a bit buggy (sometimes it does not spawn new threads and runs them in parallel, but instead reuses threads and runs task one after another). This is too slow when I'm doing expensive network calls. So I figured I'd write my own async function. I'm getting stuck though, where should std::promise live? In the 1) thread function, 2) async function, or 3) caller function.

代码:

#include <future>
#include <thread>
#include <iostream>
#include <string>
#include <vector>

std::string thFun() {
    throw std::exception("bang!");
    return "val";
}

std::future<std::string> myasync(std::promise<std::string>& prms) {
//std::future<std::string> myasync() {
    //std::promise<std::string> prms; //needs to outlive thread. How?

    std::future<std::string> fut = prms.get_future();
    std::thread th([&](){
        //std::promise<std::string> prms; //need to return a future before...
        try {
            std::string val = thFun();

            prms.set_value(val);

        } catch(...) {
            prms.set_exception(std::current_exception());
        }

     });

    th.detach();
    return fut;
}

 int main() {

    std::promise<std::string> prms; //I really want the promise hidden iway in the myasync func and not live here in caller code but the promise needs to outlive myasync and live as long as the thread. How do I do this?
    auto fut = myasync(prms);

    //auto fut = myasync(); //Exception: future already retrieved

    try {
        auto res = fut.get();
        std::cout << "Result: " << res << std::endl;

    } catch(const std::exception& exc) {
        std::cout << "Exception: " << exc.what() << std::endl;
    }

 }

事实上,std :: promise需要比async函数更长的时间(并且只要线程生存),所以promise不能作为异步func中的局部变量。但是std :: promise不应该存在于调用者代码中,因为调用者只需要知道期货。我不知道如何使承诺生活在线程函数async需要返回一个未来,甚至调用线程func。我在这一个抓我的头。

I cant seem to get past the fact that the std::promise needs to outlive the async function (and live as long as the thread), so the promise cant live as a local variable in the async func. But the std::promise shouldn’t live in in the caller code either, as the caller only need to know about futures. And i dont know how to make the promise live in the thread function as async needs to return a future before it even calls the thread func. I’m scratching my head on this one.

任何人都有任何想法吗?

Anyone got any ideas?

编辑:我在这里突出显示此处的顶部评论有点误传。虽然std :: asycn的默认值允许为dererred模式,但是当显式设置std :: launch :: async的启动策略时,它必须表现为as if线程被生成并立即运行(参见en .cppreference.com / w / cpp / thread / async)。请参见pastebin.com/5dWCjjNY中的示例,其中一个案例不是在vs20011中看到的行为。解决方案工作的很好,加速了我的现实世界的应用程序的10倍。

I'm highlighting this here as the top comment is a bit misinformed. While the default for std::asycn is allowed to be the dererred mode, when a launch policy of std::launch::async is explicitly set it must behave "as if" threads are spawned and run at once (see wording in en.cppreference.com/w/cpp/thread/async). See the example in pastebin.com/5dWCjjNY for one case where this is not the behavioured seen in vs20011. The solution works great and sped up my real world application by a factor of 10.

编辑2:MS修复了错误。更多信息:

Edit 2: MS fixed the bug. More info here: https://connect.microsoft.com/VisualStudio/feedback/details/735731/std-async-std-launch-async-does-not-behave-as-std-thread

推荐答案

这里有一个解决方案:

future<string> myasync()
{
    auto prms = make_shared<promise<string>> ();

    future<string> fut = prms->get_future();

    thread th([=](){

        try {
            string val = thFun();
            // ...
            prms->set_value(val);

        } catch(...) {
            prms->set_exception(current_exception());
        }

     });

    th.detach();

    return fut;
}

在堆上分配promise,然后传递值 [=] 一个shared_ptr到它到lambda。

Allocate promise on the heap, and then pass-by-value [=] a shared_ptr to it through to the lambda.

这篇关于将std :: async替换为自己的版本,但是std :: promise应该在哪里?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-30 19:25