为何std::future::wait_for()无法触发超时?
关于std::promise::set_value_at_thread_exit导致的挂起与崩溃问题
以下代码原本预期在远小于1秒的时间内终止:
#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); // 此处无限挂起 set_p2.request_stop(); }
但实际在MSVC 17.10环境下,程序执行到p2.get_future().wait_for(0ms)时会无限挂起,其他编译器则无此问题。
通过调试发现,p2.get_future().wait_for一直在等待一个内部的std::mutex——即便设置了0ms超时也无济于事。这个mutex被调用p2.set_value_at_thread_exit()的线程持有,具体来说,p2._MyPromise._State._Assoc_state->_Mtx在调用该函数前处于未锁定状态,调用后却始终保持锁定。
理解这个机制后,就能明白以下代码为何看似正常运行,实际却会以0xc0000409退出码崩溃:
#include <future> int main() { std::promise<void> p; p.set_value_at_thread_exit(); p.get_future().wait(); }
内容的提问来源于stack exchange,提问作者bers
相关产品推荐
相关产品推荐

