C++ detach输入线程后使用cin抛出std::system_error异常问题
问题根源
- 直接原因:你在
t1线程的lambda函数中捕获了栈上的t1对象引用,当input函数执行完毕返回后,t1对象已经被销毁,此时lambda中调用t1.detach()属于访问悬空引用,直接触发std::system_error异常。 - 潜在问题:超时后detach的
t1线程仍然阻塞在cin读取操作上,后续main函数读取temp时会出现两个线程同时竞争标准输入的情况,行为完全不可控。 - 同步问题:
sec、flag变量多线程访问没有同步机制,存在可见性问题,部分场景下会出现计时/状态判断错误。
修复方案
- 移除lambda内部对
t1对象的操作,线程执行完毕后直接在主线程join即可 - 超时场景下直接终止阻塞的读线程,避免后续输入竞争
- 用原子变量替换普通变量做状态同步,避免多线程可见性问题
- 超时后清空
cin的错误状态和输入缓冲区,保证后续输入正常
修复后代码
#include <iostream> #include <windows.h> #include <thread> #include <atomic> using namespace std; int input(int time, int *ptr) { atomic<int> sec = 0; atomic<int> flag = 0; thread t1([&]() { cin >> *ptr; if (cin.fail()) { return; } sec = 0; flag = 1; }); thread t2([&]() { while (flag == 0) { if (sec == time) { if (t1.joinable()) { // 终止超时的读线程 TerminateThread(t1.native_handle(), 0); t1.detach(); } break; } Sleep(1000); sec++; } }); t2.join(); if (t1.joinable()) { t1.join(); } // 清空cin状态和缓冲区 cin.clear(); fflush(stdin); return flag; } int start(int time, int *ptr) { return input(time, ptr); } int main() { int arr[10], flag2 = 1, count = 0; for (int i = 0; i < 10; i++) { cout << "Enter " << i + 1 << " element: "; flag2 = start(2, arr + i); if (flag2 == 0) { cout << endl; break; } count++; } cout << endl << "Array elements: "; for (int i = 0; i < count; i++) { cout << *(arr + i) << " "; } int temp; cout << "\nEnter temporary value: "; cin >> temp; cout << "Here is what you gave as input: " << temp; return 0; }
效果验证
修改后超时场景下会直接终止阻塞的读线程,不会残留线程竞争输入,也不会再出现访问悬空thread对象的异常,可以正常读取后续的temp变量,输出符合预期。
内容的提问来源于stack exchange,提问作者Akshay
相关产品推荐
相关产品推荐

