VC ++实现std :: promise

A. *_*nle 5 c++ multithreading visual-studio-2015 visual-studio-2017

我对std :: promise的VC ++实现(Visual Studio 2015和2017)都有一个奇怪的问题。set_value_at_thread_exit()似乎不像广告中所宣传的那样工作-也许我误解了该标准所允许的和它所不允许的。以下代码将在clang中编译并正常运行,但是在使用VS2015(在第二个块中)或VS2017(在第三个块中)进行编译时会崩溃:

#include <future>
#include <thread>
#include <iostream>

int main()
{
    {
        std::cout << "Safe version... ";
        std::promise<int> promise;
        auto f = promise.get_future();

        std::thread
        (
            [](std::promise<int> p) 
            { 
                p.set_value(99); 
            }, 
            std::move(promise)
        )
        .detach();

        std::cout << f.get() << std::endl;
    }

    {
        std::cout << "Will crash VS2015... ";
        std::promise<int> promise;
        auto f = promise.get_future();

        std::thread(
            [p{ std::move(promise) }]() mutable 
            { 
                p.set_value_at_thread_exit(99); 
            }
        )
        .detach();

        std::cout << f.get() << std::endl;
    }

    {
        std::cout << "Will crash VS2017... ";
        std::promise<int> promise;
        auto f = promise.get_future();

        std::thread(
            [](std::promise<int> p) 
            { 
                p.set_value_at_thread_exit(99); 
            }, 
            std::move(promise)
        )
        .detach();

        std::cout << f.get() << std::endl;
    }
}
Run Code Online (Sandbox Code Playgroud)

我试图通过慷慨地使用换行符来使差异可见。

问题似乎是在MS实现中,即使调用了set_value_at_thead_exit(),lambda函数内部的promise对象的析构函数也会尝试使用“ broken promise”异常来更新共享状态。但是,这将失败并依次引发系统错误。尝试锁定关联的互斥锁时会发生这种情况。如果未调用set_value_at_thread_exit(),则f.get()会按预期引发future_error。

在MS实现(VS2017)的内部,我发现伪装成检查线程退出时共享状态是否准备好但什么都不做的代码。因此,我想知道这是一个错误还是我是否误解了API,并应确保保证的寿命超出线程出口。

后者似乎是VS2017中第二个代码块中发生的事情,而不是VS2015中发生的事情-可能是由于std :: thread的实现差异所致!

如上所述,代码在

叮当声:http
://rextester.com/FEZDS24592 gcc:http//rextester.com/WFKE61563

但崩溃了

VS2015中的第二个块:http: //rextester.com/NODVFO14840,VS2017中
的第三个块。可以在这里进行测试:http : //webcompiler.cloudapp.net/

因此,基本上我想知道是否应该提出问题,还是因为使用了所有错误的语言而只是自欺欺人?

谢谢

A. *_*nle 2

事实证明 xxx_at_thread_exit() 在大多数当前实现中都存在问题。有关详细信息,请参阅此 Visual Studio 社区问题