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操作存在资源泄漏和多线程安全问题
- 全局变量
qstate在多线程场景下会出现竞态条件,多个线程同时调用会互相覆盖值 - mysql查询完成后没有调用
mysql_free_result释放结果集、mysql_close关闭连接,持续调用会耗尽系统资源 - 直接拼接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
相关产品推荐
相关产品推荐

