C++ 11 Promise对象无效,但其未来对象既不返回值,也不会抛出异常

发布于 2025-02-10 04:49:42 字数 1082 浏览 1 评论 0原文

我有这个测试代码可以查看,如果一个承诺对象不在生命周期之外,那么它的未来对象会发生什么:

#include <chrono>
#include <future>
#include <iostream>
#include <thread>
using namespace std;

void getValue(future<int>& future) {
    cout << "sub process 1 \n";
    try {
        cout << "sub process 2 \n";
        int value = future.get();
        cout << "sub process 3\n";
        cout << value << endl;
    } catch (future_error &e) {
        cerr << e.code() << '\n' << e.what() << endl;
    } catch (exception e) {
        cerr << e.what() << endl;
    }
    cout << "sub process 4\n";
}
int main() {
    thread t;
    {
        promise<int> plocal;
        future<int> flocal = plocal.get_future();
        t = thread(getValue, ref(flocal));
    }
    t.join();
    return 0;
}

我希望在getValue函数中,它会打印Future ::获取结果,或者抛出运行时异常并打印异常信息,因为Plocal已在“ Main”中破坏了。

从行为上讲,该程序打印:

sub process 1
sub process 2

结束。

I've got this test code to see, if a promise object is out of lifecycle, what happen to its future object:

#include <chrono>
#include <future>
#include <iostream>
#include <thread>
using namespace std;

void getValue(future<int>& future) {
    cout << "sub process 1 \n";
    try {
        cout << "sub process 2 \n";
        int value = future.get();
        cout << "sub process 3\n";
        cout << value << endl;
    } catch (future_error &e) {
        cerr << e.code() << '\n' << e.what() << endl;
    } catch (exception e) {
        cerr << e.what() << endl;
    }
    cout << "sub process 4\n";
}
int main() {
    thread t;
    {
        promise<int> plocal;
        future<int> flocal = plocal.get_future();
        t = thread(getValue, ref(flocal));
    }
    t.join();
    return 0;
}

I expect that in getValue function, it either prints future::get result, or throws out runtime exception and prints exception info, because plocal has been destructed in "main".

Acturally, this program prints:

sub process 1
sub process 2

and ends.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

怎会甘心 2025-02-17 04:49:42

您的问题与std :: Promisestd :: Future行为无关。

您只需通过将flocal对象征用到线程,在线程中访问该flocal对象来引起数据竞赛(并因此是未定义的行为),并且在主线程中也无需任何同步即可将其销毁。

无论哪种类型或类型的对象tlocal是,这都不起作用。

通过std :: Future通过std :: move

void getValue(future<int> future)

/*...*/

t = thread(getValue, std::move(flocal));

随着此更改,std :: Promise将存储a <代码> std :: future_error 共享状态中的异常,get在线程中的未来将接收并投掷。


如果您用std :: Ref将某些内容传递给线程,则您始终必须确保引用的对象要列出线程,否则您需要确保有一些同步确定主线程何时可能破坏对象的机制。

Your problem is not about std::promise or std::future behavior.

You simply cause a data race (and consequently undefined behavior) by passing the flocal object by-reference to the thread, accessing it in the thread, but also destroying it in the main thread without any synchronization.

This doesn't work no matter what type or kind of object flocal is.

Pass the std::future by-value via std::move:

void getValue(future<int> future)

/*...*/

t = thread(getValue, std::move(flocal));

With this change the destructor of std::promise will store a std::future_error exception in the shared state and get on the future in the thread will receive and throw it.


If you pass something with std::ref to a thread you always have to make sure that the referenced object outlives the thread or you need to make sure that there is some synchronization mechanism to determine when the main thread may destroy the object.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文