2012-10-19 5 views
0

QThread를 이와 같이 구현하지만 실행시 프로그램이 중단됩니다.
글을 검색하고 이라고 말하는 게시물을 보았지만 QThread를 사용하는 올바른 방법이 아닙니다.
하지만 내 프로그램의 충돌에 대한 어떤 이유도 찾을 수 없으며, 내가하는 일은 'on_Create_triggered()'을 트리거하는 것일 뿐이며 뮤텍스가 잠겨 있고 제대로 잠겨 있는지 보장합니다.
2 일 동안 테스트했는데 (이유는 'std :: cerr < < ...;'결과 만 출력합니다), 여전히 이유를 찾을 수 없습니다. (MainWindow를 :QThread가 프로그램을 충돌합니까?

#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를 Background.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(); 



}; 

Background.cpp을 : What I guess is that the thread may wait for the lock too long and cause program to crash. :

내 코드 (안 ... 합리적인 소리) 배경으로 * 다시 속성으로)

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(); 
} 
+0

그리고 어디 디버거가 추락 한 말을합니까? – cmannett85

+0

모든 곳, 거의. 아니 같은 장소 ... 혼란과 좌절되는, 표시 스레드가 자물쇠를 대기하고 있습니다. (디버거가 아닌 인쇄 된 스트림에서 찾았습니다 ... :) – Al2O3

+0

이제 내 프로그램의 QTimer를 (MainWindow에서) 의심 스럽습니다. 아무 슬롯에도 연결하지 않아도 'timer = 새로운 QTimer() '와'timer-> start (1000) '는 프로그램을 중단 시키지만 모든 것이 주석으로 처리 된 것 같습니다. :) – Al2O3

답변

0

나는 더 미묘한 이유를 발견했습니다.
(나는 다른 사람에 의해 작성된 일부 코드를 사용하지만 그것은, 내가 무엇을 가지고 완전히 잘못된 파손되지 믿습니다 :)!)
깨진 코드 :

#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 바이트의 배열 만 사용합니다. 충돌의
모든 종류의 종종 때. :(:(:(

관련 문제