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

C++线程场景中blacklist是什么?如何删除?f.get()执行后无响应该如何处理

问题根本原因

程序卡死在int valueSQLQuery = f.get();和所谓blacklist无关,核心是std::promise用法错误:你创建的promise对象从未被赋值,future会一直阻塞等待结果返回。

存在的所有问题

  • promise未传递到子线程赋值
    你定义的std::promise<int> p仅在主线程创建,没有作为参数传递给子线程的SQLQuery函数,子线程执行完成后的返回值没有写入promise,future永远等不到有效结果,直接触发永久阻塞。
  • 标识符重名冲突
    std::thread SQLQuery(SQLQuery, ID);中线程对象的名字和线程入口函数同名,会引发语法逻辑异常。
  • SQL操作存在资源泄漏和多线程安全问题
    1. 全局变量qstate在多线程场景下会出现竞态条件,多个线程同时调用会互相覆盖值
    2. mysql查询完成后没有调用mysql_free_result释放结果集、mysql_close关闭连接,持续调用会耗尽系统资源
    3. 直接拼接SQL字符串存在SQL注入风险

修正方案

第一步 修改SQLQuery函数逻辑,适配promise传值

// 修改函数参数,增加promise传值,返回值改为void
void SQLQuery(std::string ID, std::promise<int> p)
{
    int qstate = 0; // 改为局部变量,避免多线程冲突
    MYSQL* conn;
    MYSQL_ROW row;
    MYSQL_RES* res = nullptr;
    conn = mysql_init(0);
    int ret = 0; // 存储返回结果

    mysql_real_connect(conn, "localhost", "EQ", "passwor...", "eq", 3306, NULL, 0);

    if (conn) {
        std::ostringstream str;
        str << "SELECT * FROM users WHERE UserID='" << ID <<"';";
        std::string sql = str.str();

        qstate = mysql_query(conn, sql.c_str());
        if (!qstate) {
            res = mysql_store_result(conn);
            if (res->row_count == 0) {
                ret = 0;
            } else {
                while (row = mysql_fetch_row(res)) {
                    if (std::string(row[0]) == ID) {
                        if (atoi(row[7]) == 1) {
                            ret = 1;
                        } else {
                            ret = 0;
                        }
                        break; // 查到匹配结果直接退出循环
                    }
                }
            }
        } else {
            ret = 0;
        }
        // 释放mysql资源
        if (res != nullptr) {
            mysql_free_result(res);
        }
        mysql_close(conn);
    } else {
        ret = 0;
    }
    // 把结果写入promise
    p.set_value(ret);
}

第二步 修正线程调用逻辑

std::promise<int> p;
auto f = p.get_future();
// 线程对象改名,移动promise传入线程
std::thread t_sql(SQLQuery, ID, std::move(p));
t_sql.join();
int valueSQLQuery = f.get();

if (valueSQLQuery == 0 || ID.length() != 13 || ID == "0") {
    // 原有逻辑
}

内容的提问来源于stack exchange,提问作者Philipp

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 00:09:04