You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++ detach输入线程后使用cin抛出std::system_error异常问题

问题根源

  • 直接原因:你在t1线程的lambda函数中捕获了栈上的t1对象引用,当input函数执行完毕返回后,t1对象已经被销毁,此时lambda中调用t1.detach()属于访问悬空引用,直接触发std::system_error异常。
  • 潜在问题:超时后detach的t1线程仍然阻塞在cin读取操作上,后续main函数读取temp时会出现两个线程同时竞争标准输入的情况,行为完全不可控。
  • 同步问题:sec、flag变量多线程访问没有同步机制,存在可见性问题,部分场景下会出现计时/状态判断错误。

修复方案

  1. 移除lambda内部对t1对象的操作,线程执行完毕后直接在主线程join即可
  2. 超时场景下直接终止阻塞的读线程,避免后续输入竞争
  3. 用原子变量替换普通变量做状态同步,避免多线程可见性问题
  4. 超时后清空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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 12:06:03