提问者:小点点

为什么`std::promise::set_value`在从主线程调用时抛出错误?


当我运行以下代码时,

#include <future>

int main()
{
    std::promise<int> p;
    p.set_value(1);
    return 0;
}

抛出std::system_error。但是,当我在另一个线程中设置Promission的值时,

#include <future>
#include <thread>

int main()
{
    std::promise<int> p;
    std::thread([&]{p.set_value(1);}).join();
    return 0;
}

一切正常。根据我对std::promise的理解,调用set_value不应该抛出异常,除非promise没有共享状态(即它已从其中移动)或已经为其赋值,即使这样,它也会抛出std::future_error,而不是std::system_error。由于不存在数据竞争或任何类似的情况,因此无论我是从创建promise的线程还是在另一个线程中调用set_value都不重要。是不是我漏了什么?

我使用g++和clang都尝试了这一点,结果是相同的。具体地说,当我运行顶部的代码时,以下内容被输出到stderr:

terminate called after throwing an instance of 'std::system_error'
  what():  Unknown error -1
Aborted (core dumped)

这些命令用于编译顶部的代码,

g++ main_thread.cpp -o main_thread -std=c++17 -g -Og
clang main_thread.cpp -o main_thread -std=c++17 -lstdc++

这些代码用于编译底部的代码:

g++ separate_thread.cpp -o separate_thread -lpthread -std=c++17 -g -Og
clang separate_thread.cpp -o separate_thread -std=c++17 -lstdc++ -lpthread

共1个答案

匿名用户

std::promise是线程支持库的一部分,因此它需要在编译器选项(例如-pthread)中启用线程支持。