为什么 `std::promise::set_value` 从主线程调用时会抛出错误?
Why does `std::promise::set_value` throw an error when invoked from the main thread?
当我运行下面的代码时,
#include <future>
int main()
{
std::promise<int> p;
p.set_value(1);
return 0;
}
std::system_error
被抛出。但是,当我在另一个线程中设置承诺的值时,
#include <future>
#include <thread>
int main()
{
std::promise<int> p;
std::thread([&]{p.set_value(1);}).join();
return 0;
}
一切正常。根据我对 std::promise
的理解,调用 set_value
不应该抛出异常,除非承诺没有共享状态(即它已被移出)或者已经为其分配了一个值,即使那样它会抛出 std::future_error
,而不是 std::system_error
。由于不存在数据竞争或任何类似的情况,因此无论我是从创建承诺的线程还是在另一个线程中调用 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
std::promise
is part of the Thread Support Library 所以按理说它需要在编译器选项中启用线程支持(例如 -pthread
)。
请注意,-pthread
会影响编译和链接阶段。来自 man g++
:
-pthread
Adds support for multithreading with the pthreads library. This option sets flags for both the preprocessor and linker.
当我运行下面的代码时,
#include <future>
int main()
{
std::promise<int> p;
p.set_value(1);
return 0;
}
std::system_error
被抛出。但是,当我在另一个线程中设置承诺的值时,
#include <future>
#include <thread>
int main()
{
std::promise<int> p;
std::thread([&]{p.set_value(1);}).join();
return 0;
}
一切正常。根据我对 std::promise
的理解,调用 set_value
不应该抛出异常,除非承诺没有共享状态(即它已被移出)或者已经为其分配了一个值,即使那样它会抛出 std::future_error
,而不是 std::system_error
。由于不存在数据竞争或任何类似的情况,因此无论我是从创建承诺的线程还是在另一个线程中调用 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
std::promise
is part of the Thread Support Library 所以按理说它需要在编译器选项中启用线程支持(例如 -pthread
)。
请注意,-pthread
会影响编译和链接阶段。来自 man g++
:
-pthread
Adds support for multithreading with the pthreads library. This option sets flags for both the preprocessor and linker.