为何示例代码中出现std::future_error: No associated state错误?
std::future_error: No associated state 错误原因及修复
错误根源
主线程过早操作空future
你在主线程创建t1后立刻调用future.wait_for,但此时t1线程大概率还没执行到refFuture = std::move(future);这一步——main里的future还是个没有绑定任何共享状态的空对象。对空std::future调用wait_for、get这类方法,必然会抛出no_state类型的future_error。packaged_task生命周期不匹配
task函数里的mytask是局部变量,函数执行完它就会被销毁。但你调用了mytask.make_ready_at_thread_exit(),这个函数是安排线程退出时才把任务结果标记为ready,可此时packaged_task已经被销毁,后续操作会触发未定义行为。
修复方法
方法一:等线程完成后再操作future
最简单的方式是先调用t1.join()等待线程执行完毕,确保future已经被正确赋值后再进行后续判断:
#include <iostream> #include <thread> #include <future> #include <chrono> #include <functional> void task(int& var, std::future<int>& refFuture) { std::packaged_task<int()> mytask{ [&](){var = 25; return var;}}; auto future = mytask.get_future(); mytask(); // 直接执行任务,不用延迟到线程退出 refFuture = std::move(future); } int main() { int variable = 10; std::future<int> future; std::thread t1(task, std::ref(variable), std::ref(future)); t1.join(); // 先等线程跑完,保证future有状态 std::future_status status = future.wait_for(std::chrono::seconds(0)); if(status == std::future_status::ready) { int myOutput = future.get(); std::cout << "Myoutput :" << myOutput << std::endl; } }
方法二:用std::async替代手动线程管理(更简洁)
如果不需要手动控制线程,std::async会自动帮你处理future和任务的绑定,避免手动传递future的麻烦:
#include <iostream> #include <future> #include <chrono> int task(int& var) { var = 25; return var; } int main() { int variable = 10; // 用std::launch::async强制开启新线程 auto future = std::async(std::launch::async, task, std::ref(variable)); // 这里wait_for不会报错,因为future已经绑定了共享状态 std::future_status status = future.wait_for(std::chrono::seconds(0)); if(status == std::future_status::ready) { int myOutput = future.get(); std::cout << "Myoutput :" << myOutput << std::endl; } // 或者直接调用get,get会自动等待任务完成 // int myOutput = future.get(); // std::cout << "Myoutput :" << myOutput << std::endl; }
注意点
- 只有当
std::future绑定了共享状态(比如通过packaged_task::get_future、std::async、promise::get_future创建)时,才能调用wait、wait_for、get这些方法。 - 使用
make_ready_at_thread_exit时,必须保证packaged_task对象的生命周期至少覆盖到线程退出,不然会出现未定义行为。
内容的提问来源于stack exchange,提问作者Mangy
相关产品推荐
相关产品推荐

