本案例主要是QString的【隐式共享】引发,由此,关注多线程中隐式共享的使用要万分小心:
【隐式共享】——https://zhuanlan.zhihu.com/p/45354267
主线程中:
if (nullptr!=ptrAlarm)
{
LOG_DEBUG("----end added card of alarm=(%s), at time=(%I64d)----",
ptrAlarm->eventId.toStdString().c_str(),
QDateTime::currentMSecsSinceEpoch());
// 添加报警到UI
this->addRealFace(ptrAlarm);
// 回收报警空间
if (nullptr!=ptrAlarm)
{
delete ptrAlarm;
}
}
工作子线程中:
//------------------------ 组装请求报文开始 ------------------------//
//
QJsonObject json_object;
json_object.insert("guideState", cond.guideState);
json_object.insert("plateNo", cond.plateNo);//隐式共享,造成这里堆栈破坏
json_object.insert("routeId", cond.routeId);
json_object.insert("routeOfForeign", cond.routeOfForeign);
// 生成请求报文内容
QJsonDocument json_doc;
json_doc.setObject(json_object);
std::string request_json = json_doc.toJson(QJsonDocument::Compact);
//
//------------------------ 组装请求报文结束 ------------------------//
解决隐式共享,不使用QString的赋值,即:
// 出场压线事件、停止线路引导
QtConcurrent::run([=]
{
hwb_client_data::GuideLineInfoCond cond;
hwb_client_data::Messageback message;
cond.guideState = hwb_client_data::TWGuideControl_Stop;//线路引导状态
//cond.plateNo = ptrInfo->plateNo;//车牌(ptrInfo销毁后,程序就崩了)
//cond.plateNo = QString::fromStdString(ptrInfo->plateNo.toStdString());//车牌
cond.plateNo = ptrInfo->plateNo.toStdString().c_str();//车牌
// 引导完毕出场操作
if (!DataManager::instance()->VisitorGuideConfirm(cond,message))
{
LOG_ERROR(u8"引导线路出场状态设置失败!");
}
}
);
一旦隐式共享的宿主消失,堆栈被破坏,后续就危险了:
//cond.plateNo = ptrInfo->plateNo;//车牌(ptrInfo销毁后,程序就崩了)
//cond.plateNo = QString::fromStdString(ptrInfo->plateNo.toStdString());//车牌
cond.plateNo = ptrInfo->plateNo.toStdString().c_str();//车牌