如何避免std::future.wait_for与std::thread::sleep_for资源竞争?求解挂起问题
问题描述
遇到std::future.wait_for长时间等待导致程序挂起的问题,相关代码如下:
while ((future.wait_for(std::chrono::milliseconds(50))) != std::future_status::ready) { sendHeartBeat(); }
挂起时的调用栈信息:
Count:48|(0xb8d8ed)std::condition_variable::wait_for<__int64,std::ratio<1,1000>,std::_Associated_state<int>::_Test_ready>+0x19d Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\include\mutex:627+0x174 Count:38|MSVCP140.dll - 0x12e03 - _Cnd_timedwait Count:38|MSVCP140.dll - 0x12c55 - ?_Winerror_message@std@@YAKKPEADK@Z Count:29|KERNELBASE.dll - 0x6dc69 - SleepConditionVariableSRW Count:23|KERNELBASE.dll - 0x730e9 - SleepConditionVariableSRW Count:8|KERNELBASE.dll - 0x76339 - SleepConditionVariableSRW Count:2|KERNELBASE.dll - 0x6d059 - SleepConditionVariableSRW Count:1|KERNELBASE.dll - 0x76b99 - SleepConditionVariableSRW Count:10|MSVCP140.dll - 0x12d83 - _Cnd_timedwait Count:10|MSVCP140.dll - 0x12bd5 - ?_Winerror_message@std@@YAKKPEADK@Z
需求:避免std::future.wait_for与std::thread::sleep_for的资源竞争。
解决方案
改用
std::future.wait_until替代wait_forwait_for依赖系统时钟,时钟变更(如NTP同步、手动修改)会导致等待时长异常。wait_until基于绝对时间,不受时钟调整影响:auto end_time = std::chrono::steady_clock::now() + std::chrono::milliseconds(50); while (future.wait_until(end_time) != std::future_status::ready) { sendHeartBeat(); end_time = std::chrono::steady_clock::now() + std::chrono::milliseconds(50); }确保
sendHeartBeat无阻塞操作
若sendHeartBeat内部调用std::thread::sleep_for或其他阻塞API,会与wait_for的条件变量等待产生资源竞争。限制sendHeartBeat为轻量操作,仅完成心跳发送逻辑,不做长时间阻塞。显式指定
std::async的启动策略
若future由std::async创建,默认策略可能为延迟启动(std::launch::deferred),导致wait_for无限等待。显式指定std::launch::async强制创建独立线程:auto future = std::async(std::launch::async, [](){ // 异步任务执行逻辑 });验证异步任务的状态设置
确保异步任务正确调用std::promise::set_value或std::packaged_task::operator()完成状态设置,避免因任务未正确结束导致wait_for持续等待。
内容的提问来源于stack exchange,提问作者Manoj Hanamshet
相关产品推荐
相关产品推荐

