QString多线程安全使用小贴士

本文通过一个实例展示了在多线程环境中如何因为QString的隐式共享特性引发的问题,强调了在主线程和工作子线程中处理这类数据时的注意事项。解决方案是避免直接赋值,而是采用深拷贝的方式,例如使用toStdString().c_str(),以防止堆栈破坏和程序崩溃。
摘要由CSDN通过智能技术生成

本案例主要是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();//车牌

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值