发行版本意外地工作 - 内存竞争和奇怪的QThread行为

时间:2014-05-21 12:37:37

标签: c++ multithreading qt memory-leaks

我在调试模式下编写了整个应用程序,在这种模式下一切正常。不幸的是,现在当我试图运行发布应用程序时,两个意外的事情发生 基本信息: Qt 5.1.1 Qt Creator 2.8.1 Windows 7 64x 应用程序有第二个线程,它从主线程中更新的缓冲区中解封装数据。

第一个问题 - 记忆竞赛: 在我的一种方法中,奇怪的内存竞争在发布版本中发生 - 在调试中一切正常。方法如下:

std::vector<double> dataVec;
std::vecotr<unsigned char> frame("U+014-00300027950l");
//EFrame_AccXPos == 1;
dataVec.push_back(decapsulateAcc(frame.begin()+EFrame_AccXPos));

        double Deserializator::decapsulateAcc(std::vector<unsigned char>::iterator pos)
        {
            const char frac[2] = {*(pos+2),*(pos+3)};
            const char integ[] = {*(pos+1)};
            double sign;

            if (*pos == consts::frame::plusSign) {
                sign = 1.0;
            } else {
                sign = -1.0;
            }
            double integer = (std::strtod(integ, 0));
            double fractial = (std::strtod(frac, 0))/100;

            qDebug() << QString::fromStdString(std::string(integ));
                //prints "014Rd??j?i" should be "0 ?s"
            qDebug() << QString::number(integer);
                //prints "14" should be "0"
            qDebug() << QString::number(fractial);
                //prints "0.14" - everything ok.

            return sign*integer+sign*fractial;
        }

这种方法有什么问题?

第二个问题: 在附加线程中,我发出信号来管理从缓冲区解封的数据。发出线程后等待,直到标志变为false。当我添加一些qDebug打印时 - 它开始工作,但没有它们就会阻塞(即使标志已经是假的)。代码如下:

    void DataManager::sendPlottingRequest()
    {
        numberOfMessurement++;
        if (numberOfMessurement == plotAfterEquals ) {
            numberOfMessurement = consts::startsFromZero;
            isStillPlotting=true;
            emit requestPlotting(dataForChart);
                //block in next line
            while (isStillPlotting);
            //it starts work when:
            //int i = 0;
            //while (isStillPlotting) {
            //i++
            //if (i == 10000) qDebug() << isStillPlotting;
            //}
        }
    }

void DataManager::continueProcess()
{
    plottingState++;
    if (plottingState == consts::plottingFinished) {
            //program reach this point
        isStillPlotting = false;
        plottingState = consts::startsFromZero;
    }
}

1 个答案:

答案 0 :(得分:1)

while (isStillPlotting);优化至if(isStillPlotting)while(true);

你应该使isStillPlotting不稳定或改为使用atomicInt。

或者您可以从plottingDone()中的if发出信号continueProcess(),然后连接执行代码之后的代码的插槽