English 中文(简体)
1. 承诺和设定的终身价值_at_thread_exit
原标题:Lifetime of promise and set_value_at_thread_exit

Suppose we have the following code:

std::promise<int> promise;
auto future = promise.get_future();

const auto task = [](auto promise) {
    try {            
        promise.set_value_at_thread_exit(int_generator_that_can_throw());
    } catch (...) {
        promise.set_exception_at_thread_exit(std::current_exception());
    }
};
    
std::thread thread(task, std::move(promise));
// use future
thread.join();

我想知道这部法典是否正确和安全,如果没有,为什么。

It appears to work fine when compiled with GCC, but crashes (no message is printed) when compiled with MSVC (2017). My guess is that a crash happens because promise local variable inside task goes out of scope and is destroyed too early. If I remove _at_thread_exit suffixes, this code works as expected (or appears to work). It also works correctly when the promise is captured:

const auto task = [p = std::move(promise)]() mutable {
    /*...*/
};

Complete codificationable example

最佳回答
问题回答
#include <future>

int main()
{
    auto promise = std::make_shared<std::promise<int>>();
    auto future = promise->get_future();

    const auto task = [](const std::shared_ptr<std::promise<int>>& p) 
    {
        try 
        {
            p->set_value_at_thread_exit(42);
        }
        catch (...) 
        {
            p->set_exception_at_thread_exit(std::current_exception());
        }
    };

    std::thread thread(task, promise);
    // use future
    thread.join();

    return 0;
}

我最近努力理解未来机制,并遇到同样的问题。 我阅读了源代码和C++标准,最后列出情况。 问题并不在于“为了获得垃圾记忆,可以进行净化”。

TL;DR

您的编号为<代码>std:promise destruct before the readwals,因为它将试图确定价值和例外。 看来,MS-STL在标准中做了规定,而libc++/libstdc++则是t。

Future-Promise model

在C++中,一项承诺是“允准取得某种成果”的工人,而未来则是“未来结果”的采集者。 它们在共同国家中占有一席之地,其结果(价值或例外)存放在那里。 而且,这种联系是一个非渠道,这意味着每个目的只能一度确定/确定结果,除非您将<代码>td:future变成std:共有_future<>/code>,使之得以多次获得。

共有3起案件:

  • Neither set result, nor ready; std::promise may call set_value, set_exception, set_value_at_thread_exit and set_exception_at_thread_exit once.
  • Set result, but not ready; This is because std::promise calls xx_at_thread_exit, so it ll be ready when the thread is joined/detached (yet after all local variables are destructed).
  • Set result, and ready; This is because set_value or set_exception, or xx_at_thread_exit when the thread completely exits.

尤其是,当这一承诺在准备就绪之前被破坏时,共同国家将被列入abandoned,意思是,将设定一个例外(std:future_error(即允诺)。

共同国家就像一个<代码>std:共有-ptr。 由<代码>std:future <>/code>和共同持有:promise<>/code>;无论何人指示编号为-1,只要参考数字为0,共同国家即予删除。

Lifetime concern

因此,我们现在知道,在打电话xx_at_thread_exit后,结果将予以储存。 制作<条码> 完全在共同国家发生(通常实施将储存条件变数并登记这种活动),不会干扰销毁<代码>td:promise<<>/code>。 因此,我要说的是,问题并不在于“为了获取垃圾记忆,正在破坏宣传”。

那么,“MS-STL”为什么会终止该方案? 这是因为C++标准规范 检查是否确定了结果,但检查是否准备就绪。 But _ Value_at_thread_exit 否则,将确定例外(std:future_error(broken_promise)。

然而,共同国家应该有价值或例外。 MS-STL基本上只是电话set_ Tenion,因此,储存的价值使其投下std:future_err (promise_already_satisfied)。 但是,它载于<条码>中。 http://www.un.org/Depts/DGACM/index_french.htm

libc++/libstdc++,std:promise 一旦设定,将切断与储存结果的联系。 因此,这种例外情况在拖拉机上被打上,而且程序正常运行。 这稍微违反了标准,因为它既具有价值,也具有例外;但随后将违反今后的推广模式。 因此,除非对标准进行修改,否则,实施MS-STL对我来说更为合理,既符合标准,又符合抽象的模式。





相关问题
Undefined reference

I m getting this linker error. I know a way around it, but it s bugging me because another part of the project s linking fine and it s designed almost identically. First, I have namespace LCD. Then I ...

C++ Equivalent of Tidy

Is there an equivalent to tidy for HTML code for C++? I have searched on the internet, but I find nothing but C++ wrappers for tidy, etc... I think the keyword tidy is what has me hung up. I am ...

Template Classes in C++ ... a required skill set?

I m new to C++ and am wondering how much time I should invest in learning how to implement template classes. Are they widely used in industry, or is this something I should move through quickly?

Print possible strings created from a Number

Given a 10 digit Telephone Number, we have to print all possible strings created from that. The mapping of the numbers is the one as exactly on a phone s keypad. i.e. for 1,0-> No Letter for 2->...

typedef ing STL wstring

Why is it when i do the following i get errors when relating to with wchar_t? namespace Foo { typedef std::wstring String; } Now i declare all my strings as Foo::String through out the program, ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

Window iconification status via Xlib

Is it possible to check with the means of pure X11/Xlib only whether the given window is iconified/minimized, and, if it is, how?