【问题标题】:QThread crashes the program?QThread 使程序崩溃?
【发布时间】:2012-10-19 14:55:09
【问题描述】:

我这样实现 QThread,但是运行时程序崩溃了。
我搜索并看到帖子说这不是使用 QThread 的正确方法。
但是我找不到程序崩溃的任何原因,我所做的只是 触发“on_Create_triggered()”,我保证互斥锁已正确锁定和解锁。
我已经对该程序进行了两天的测试(仅通过 'std::cerr What I guess is that the thread may wait for the lock too long and cause program to crash. (听起来不合理...) :)

我的代码:

背景.h

class Background : public QThread
{
    Q_OBJECT

public:
    Background(int& val,DEVMAP& map, QQueue<LogInfoItem*>& queue, QList<DEV*>& devlist, QList<IconLabel*>& icllist,QMutex& m)
        :val_i(val),DevMap(map), LogInfoQueue(queue), DevInfoList(devlist), IconLabelList(icllist),mutex(m)
    {}

     ~Background();

protected:
    void run(void);


private:
    DEVMAP& DevMap;
    QQueue<LogInfoItem*>&LogInfoQueue;
    QList<DEV*>& DevInfoList;
    QList<IconLabel*>& IconLabelList;
    int& val_i;
    QMutex& mutex;



    void rcv();



};

背景.cpp

#include "background.h"


Background::~Background()
{
    LogFile->close();
}

void Background::run(void)
{
    initFile();

    while(1)
    {
        msleep(5);
        rcv();
    }

}


void Background::rcv()
{
    mutex.lock();
    ...
    ...//access DevMap, LogInfoQueue, DevInfoList, IconLabelList and val_i;
    ...
    mutex.unlock();
}

MainWindow:(MainWindow 有 Background* 作为属性)

void MainWindow::initThread()
{
    back = new Background(val_i, dev_map, logDisplayQueue, devInfoList, iconLabelList, mutex);
    back->start();
}

void MainWindow::on_Create_triggered()
{
    mutex.lock();
    ...
    ...//access DevMap, LogInfoQueue, DevInfoList, IconLabelList and val_i;
    ...
    mutex.unlock();
}

【问题讨论】:

  • 你的调试器说它在哪里崩溃了?
  • 几乎任何地方。不是同一个地方。通常当线程等待锁时。(我从不是由调试器打印出来的流中找到它...:)
  • 现在我真的怀疑我的程序中有一个 QTimer(在 MainWindow 中)。即使我没有将它连接到任何 SLOT,但 'timer = new QTimer()' 和 'timer->start(1000)' 会使程序崩溃,但在这两个注释的情况下,一切似乎都很好...... :)
  • 您没有为任何人提供足够的信息(代码)来帮助您。您似乎还暗示 QThread 和/或 QTimer 正在导致您的崩溃。谷歌“选择没有坏”。这些类中的任何一个都不太可能导致您的崩溃。这很可能是您的代码中的问题。
  • 好的,谢谢!!!谢谢你的提示!!我只是对我使用的东西没有足够的信心,比如 QThread 或 Qtimer,并且担心它们之间存在一些意想不到的不安全链接,我什至想更改为使用 Pthread 或 std::thread 因为 QThread 的错误 cmet。但现在我完全相信 qt 库提供的东西,而且我找到了原因……(见我的回答:))

标签: multithreading qt crash mutex qthread


【解决方案1】:

我找到了原因,这更微妙。
(我使用了一些别人写的代码,但相信它没有被破坏,我完全错了!:))
损坏的代码:

#define   DATABUFLEN    96

typedef struct Para//totally  100bytes
{
    UINT8 type;
    UINT8 len;
    UINT8 inType;
    UINT8 inLen;
    UINT8 value[DATABUFLEN];//96 bytes here
}ERRORTLV;


class BitState
{

public:
    UINT8                           dataBuf[DATABUFLEN];
    ......

};

以及使用它的功能:

bool    BitState::rcvData()               //the function crosses bound of array
{

    UINT8 data[12] = 
        {
            0x72, 0x0A, 0x97, 0x08,
            0x06, 0x0A, 0x0C, 0x0F,
            0x1E, 0x2A, 0x50, 0x5F,
        };                                //only 12 bytes

    UINT32 dataLen = 110;

    memcpy(this->dataBuf, data, dataLen); //copy 110 bytes to dataBuf //but no error or warning from compiler, and no runtime error indicates the cross
}


bool    BitState::parseData(BitLog* bitLog)//pass pointer of dataBuf to para_tmp, but only use  0x08 + 4 = 12 bytes of dataBuf
{


    Para* para_tmp;
    if(*(this->dataBuf) == 0x77)
    {
        para_tmp = (ERRORTLV*)this->dataBuf;
    }

    if(para_tmp->type != 0x72 || para_tmp->inType != 0x97 || (para_tmp->len - para_tmp->inLen) != 2)                                                        // inLen == 0x08
    {
        return false;
    }
    else
    {
        //parse dataBuf according to Para's structure


        this->bitState.reset();


        for(int i = 0; i < para_tmp->inLen; i++)          // inLen == 0x08 only !!!
        {
            this->bitState[para_tmp->value[i]-6] = 1;
        }


        if(this->bitState.none())
            this->setState(NORMAL);
        else
            this->setState(FAULT);

         QString currentTime = (QDateTime::currentDateTime()).toString("yyyy.MM.dd hh:mm:ss.zzz");

         string sysTime = string((const char *)currentTime.toLocal8Bit());

         this->setCurTime(sysTime);

        this->addLog(sysTime, bitLog);

    }

    return true;
}



bool    BitState::addLog(std::string sysTime, BitLog* bitLog)// this function is right
{

        bitLog->basicInfo = this->basicInfo;//not in data Buf, already allocated and initialized, (right)
        bitLog->bitState = this->bitState;  //state is set by setState(..)

        bitLog->rcvTime = sysTime;          //time 

        return true;
}

一般来说,程序会为一个字节数组分配96个字节,但是使用'memcpy(...)'将110个字节复制到数组中,以后只使用12个字节的数组。
各种崩溃出现,令人困惑和沮丧...:( :( :(

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-30
    • 1970-01-01
    • 1970-01-01
    • 2023-01-30
    • 2018-05-03
    • 1970-01-01
    相关资源
    最近更新 更多