#include <atomic>
#include <chrono>
#include <future>
#include <stop_token>
#include <thread>
using namespace std::chrono_literals;
std::atomic_bool p2_is_set{false};
std::promise<void> p2;
int main() {
std::jthread set_p2([](const std::stop_token& token) {
p2.set_value_at_thread_exit();
p2_is_set = true;
p2_is_set.notify_one();
while (!token.stop_requested()) {
std::this_thread::sleep_for(100ms);
}
});
p2_is_set.wait(false);
p2.get_future().wait_for(0ms); // this hangs
set_p2.request_stop();
}
不幸的是,它无限期地挂在
p2.get_future().wait_for(0ms)
中,我想知道为什么。我可以在MSVC 17.10中复制该问题(
Https://godbolt.org/z/a3mfhwftj),但不能在其他编译器中。 一些其他调试表明
p2.get_future().wait_for
正在等待内部std::mutex
-这意味着实际的超时值应该无关紧要。该
mutex
由称为
p2.set_value_at_thread_exit()
的线程所有。具体而言,
p2._MyPromise._State._Assoc_state->_Mtx
在
p2.set_value_at_thread_exit()
之前解锁,然后仍然锁定。说明这一点,很容易理解为什么此代码似乎有效,但实际上只是用
0xc0000409
退出代码崩溃:
#include <future>
int main() {
std::promise<void> p;
p.set_value_at_thread_exit();
p.get_future().wait();
}
这似乎是MSVC/STL错误。 Microsoft在Https://developercommunity.visualstudio.com/t/after-calling-std :: Promise :: Set_Value_AT/10205605