Use Qt thread correctly
-
How to use qthread with mutex?
Here is my old code:
Header:class QTcpSocket; class CAgilentLan : public QThread { public: typedef enum { enRspTimeout = -2, enRspOffline, enRspOK, enRspError } t_enRspType ; CAgilentLan(QString strIpAdress_p, int iTimeout_p, bool boSimulate_p=false, bool boDebug_p=false); ~CAgilentLan(); // High-Level Funktionen QByteArray ExecuteGetScreenshot(void); void ExecuteSaveScreenshot(QString &strPathFileName_p, const char *strFormat_p); void ExecuteSettingsSave(unsigned char ucRegisterNo_p); void ExecuteSettingsRecall(unsigned char ucRegisterNo_p); double ExecuteQuickMeasure(unsigned char ucChannel_p, char *pchType_p); double ExecuteStatMeasure(char *pchType_p, bool boTrigger_p); void ExecuteResetMeasurementStatistics(void); bool Open(const QString &strIpAdress_p, const int iTimeout_p); bool Close(const int iTimeout_p); t_enRspType Execute(const char *strCmd_p, const int iWaitResponse_p, const int iTimeout_p, const int iRspDelayed_p); QByteArray GetLastResponse(void); t_enRspType ExecuteSimulated(const char *strCmd_p); QString GetAgilentIdentifikation(); ... protected: void run(); private: bool m_boDebug; bool m_boSimulate; QMutex m_MtxProcess; QMutex m_MtxResponse; QWaitCondition m_WaitCondProcess; QByteArray m_ByteArrayWrite; QByteArray m_ByteArrayRead; QByteArray m_IDN_AgilentIdentification; //Hilfsvariable double m_SDDevPeriodeA ; double m_SDDevDCA; double m_SDDevDCB; double m_SDDevWidthZ; double m_OZiSDDevPeriodeA; double m_OZiSDDevDCA; double m_OZiSDDevDCB; double m_OZiSDDevWidthZ; double m_OZiMeanPeriodeA; double m_OZiMeanDCA; double m_OZiMeanDCB; double m_OZiMeanWidthZ; QByteArray m_ByteSTDD; QByteArray m_ByteMean; QStringList m_ListSTDDev; QStringList m_ListMean; QTcpSocket *m_pTcpSctCtrl; QString m_strCtrlIP; int m_iTimeoutClose; int m_iTimeout; int m_iResponseDelayed; int m_iWaitResponse; t_enRspType m_enRetVal; };
Cpp File:
CAgilentLan::CAgilentLan(QString strIpAdress_p, int iTimeout_p, bool boSimulate_p, bool boDebug_p):m_SDDevPeriodeA(0), m_SDDevDCA(0),m_SDDevDCB(0),m_SDDevWidthZ(0) { // boSimulate_p = false; m_boDebug = boDebug_p; m_boSimulate = boSimulate_p; m_enRetVal = enRspOffline; m_strCtrlIP = QString(""); m_iTimeout = 0; m_iTimeoutClose = iTimeout_p; if (this->Execute("CreateObject", 0, 0, 0) != enRspOK) { throw(QString("Error AgilentLan.CPP/Constructor TcpSocket Create memory error")); } this->Open(strIpAdress_p, iTimeout_p); } CAgilentLan::~CAgilentLan() { while(isRunning()); this->Close(m_iTimeoutClose); while(isRunning()); if (this->Execute("DeleteObject", 0, 0, 0) != enRspOK) { throw(QString("Error AgilentLan.CPP/Destructor TcpSocket Delete memory error")); } while(isRunning()); } bool CAgilentLan::Open(const QString &strCtrlIP_p, const int iTimeout_p) { bool boRet_l = true; m_strCtrlIP = strCtrlIP_p; if (this->Execute("OpenConnection", 0, iTimeout_p, 0) != enRspOK) { throw(QString("Error AgilentLan.CPP/Open TcpSocket Open Connection error")); } if (m_boDebug) { throw(QString("Tcp Socket is open")); } return boRet_l; } bool CAgilentLan::Close(const int iTimeout_p) { bool boRet_l = true; while(isRunning()); if (this->Execute("CloseConnection", 0, iTimeout_p, 0) != enRspOK) { throw(QString("Error AgilentLan.CPP/Close Connection error")); } if (m_boDebug) { throw(QString("Tcp Socket is closed")); } while(isRunning()); return boRet_l; } CAgilentLan::t_enRspType CAgilentLan::Execute(const char *strCmd_p, const int iWaitResponse_p, const int iTimeout_p, const int iRspDelayed_p) { CAgilentLan::t_enRspType enRetVal_l = enRspOffline; if (!isRunning()) { m_ByteArrayRead.clear(); m_ByteArrayWrite.clear(); m_ByteArrayWrite.append(strCmd_p); m_iWaitResponse = iWaitResponse_p; m_iTimeout = iTimeout_p; m_iResponseDelayed = iRspDelayed_p; start(); m_MtxProcess.lock(); m_WaitCondProcess.wait(&m_MtxProcess,-1); m_MtxProcess.unlock(); enRetVal_l = this->m_enRetVal; } else { enRetVal_l = enRspError; } while(isRunning()); return enRetVal_l; } QByteArray CAgilentLan::GetLastResponse(void) { QByteArray ay_l; m_MtxResponse.lock(); ay_l = m_ByteArrayRead; m_MtxResponse.unlock(); return ay_l; } void CAgilentLan::run() { bool boRun_l = true; bool boSent_l = false; const char *pStrCmd_l = NULL; const char *pStrRsp_l = NULL; m_enRetVal = enRspError; if (strcmp(m_ByteArrayWrite.data(),"CreateObject")==0) { if (this->m_boSimulate == true) { m_enRetVal = enRspOK; } else { m_pTcpSctCtrl = (QTcpSocket *)new QTcpSocket; if (m_pTcpSctCtrl != NULL) { m_enRetVal = enRspOK; } } boRun_l = false; } if (strcmp(m_ByteArrayWrite.data(),"DeleteObject")==0) { if (this->m_boSimulate == true) { } else { if (m_pTcpSctCtrl != NULL) { delete m_pTcpSctCtrl; } } m_enRetVal = enRspOK; boRun_l = false; } if (strcmp(m_ByteArrayWrite.data(),"OpenConnection")==0) { if (this->m_boSimulate == true) { m_enRetVal = enRspOK; } else { m_pTcpSctCtrl->connectToHost(m_strCtrlIP,5025); if (m_pTcpSctCtrl->waitForConnected(m_iTimeout) == true) { m_enRetVal = enRspOK; } } boRun_l = false; } if (strcmp(m_ByteArrayWrite.data(),"CloseConnection")==0) { if (this->m_boSimulate == true) { m_enRetVal = enRspOK; } else { m_pTcpSctCtrl->disconnectFromHost(); if ((m_pTcpSctCtrl->state() == QAbstractSocket::UnconnectedState) || (m_pTcpSctCtrl->waitForDisconnected(m_iTimeout))) { m_enRetVal = enRspOK; } } boRun_l = false; } int iTimeout_l = m_iTimeout; while (boRun_l && (!this->m_boSimulate)) { if (boSent_l == false) { boSent_l = true; // Kommando absetzen m_pTcpSctCtrl->write(m_ByteArrayWrite.data(),m_ByteArrayWrite.size()); // Auf Antwort warten if (m_iWaitResponse >= 0) { QThread::msleep(m_iWaitResponse); } else { boRun_l = false; } } // Anwort auf Kommando abwarten if ((m_pTcpSctCtrl->bytesAvailable() > 0) && (boRun_l == true)) { m_MtxResponse.lock(); m_ByteArrayRead.append(m_pTcpSctCtrl->readAll()); if (m_boDebug) { throw(QString(m_ByteArrayRead.data())); } m_MtxResponse.unlock(); iTimeout_l = m_iTimeout; // iTimeout_l = m_iWaitResponse; } else { if (m_pTcpSctCtrl->waitForReadyRead(iTimeout_l) == false) { m_MtxResponse.lock(); if (m_ByteArrayRead.size() == 0) { if (m_boDebug) { throw(QString("AgilentLan Timeout")); } m_enRetVal = enRspTimeout; } else { m_enRetVal = enRspOK; } m_MtxResponse.unlock(); boRun_l = false; } } } QThread::msleep(m_iResponseDelayed); QMutexLocker locker(&m_MtxProcess); m_WaitCondProcess.wakeOne(); }
This code section I have adapted to the following:
class CAgilentLan : public QObject { Q_OBJECT public: ... CAgilentLan(QString strIpAdress_p, int iTimeout_p, bool boSimulate_p=false, bool boDebug_p=false); ~CAgilentLan(); ... t_enRspType Execute(const char *strCmd_p, const int iWaitResponse_p, const int iTimeout_p, const int iRspDelayed_p); .. public slots: void init(); void openCommunikation(); void AgilentStart(); signals: void finished(); .... };
what is wrong?
-
How to use qthread with mutex?
Here is my old code:
Header:class QTcpSocket; class CAgilentLan : public QThread { public: typedef enum { enRspTimeout = -2, enRspOffline, enRspOK, enRspError } t_enRspType ; CAgilentLan(QString strIpAdress_p, int iTimeout_p, bool boSimulate_p=false, bool boDebug_p=false); ~CAgilentLan(); // High-Level Funktionen QByteArray ExecuteGetScreenshot(void); void ExecuteSaveScreenshot(QString &strPathFileName_p, const char *strFormat_p); void ExecuteSettingsSave(unsigned char ucRegisterNo_p); void ExecuteSettingsRecall(unsigned char ucRegisterNo_p); double ExecuteQuickMeasure(unsigned char ucChannel_p, char *pchType_p); double ExecuteStatMeasure(char *pchType_p, bool boTrigger_p); void ExecuteResetMeasurementStatistics(void); bool Open(const QString &strIpAdress_p, const int iTimeout_p); bool Close(const int iTimeout_p); t_enRspType Execute(const char *strCmd_p, const int iWaitResponse_p, const int iTimeout_p, const int iRspDelayed_p); QByteArray GetLastResponse(void); t_enRspType ExecuteSimulated(const char *strCmd_p); QString GetAgilentIdentifikation(); ... protected: void run(); private: bool m_boDebug; bool m_boSimulate; QMutex m_MtxProcess; QMutex m_MtxResponse; QWaitCondition m_WaitCondProcess; QByteArray m_ByteArrayWrite; QByteArray m_ByteArrayRead; QByteArray m_IDN_AgilentIdentification; //Hilfsvariable double m_SDDevPeriodeA ; double m_SDDevDCA; double m_SDDevDCB; double m_SDDevWidthZ; double m_OZiSDDevPeriodeA; double m_OZiSDDevDCA; double m_OZiSDDevDCB; double m_OZiSDDevWidthZ; double m_OZiMeanPeriodeA; double m_OZiMeanDCA; double m_OZiMeanDCB; double m_OZiMeanWidthZ; QByteArray m_ByteSTDD; QByteArray m_ByteMean; QStringList m_ListSTDDev; QStringList m_ListMean; QTcpSocket *m_pTcpSctCtrl; QString m_strCtrlIP; int m_iTimeoutClose; int m_iTimeout; int m_iResponseDelayed; int m_iWaitResponse; t_enRspType m_enRetVal; };
Cpp File:
CAgilentLan::CAgilentLan(QString strIpAdress_p, int iTimeout_p, bool boSimulate_p, bool boDebug_p):m_SDDevPeriodeA(0), m_SDDevDCA(0),m_SDDevDCB(0),m_SDDevWidthZ(0) { // boSimulate_p = false; m_boDebug = boDebug_p; m_boSimulate = boSimulate_p; m_enRetVal = enRspOffline; m_strCtrlIP = QString(""); m_iTimeout = 0; m_iTimeoutClose = iTimeout_p; if (this->Execute("CreateObject", 0, 0, 0) != enRspOK) { throw(QString("Error AgilentLan.CPP/Constructor TcpSocket Create memory error")); } this->Open(strIpAdress_p, iTimeout_p); } CAgilentLan::~CAgilentLan() { while(isRunning()); this->Close(m_iTimeoutClose); while(isRunning()); if (this->Execute("DeleteObject", 0, 0, 0) != enRspOK) { throw(QString("Error AgilentLan.CPP/Destructor TcpSocket Delete memory error")); } while(isRunning()); } bool CAgilentLan::Open(const QString &strCtrlIP_p, const int iTimeout_p) { bool boRet_l = true; m_strCtrlIP = strCtrlIP_p; if (this->Execute("OpenConnection", 0, iTimeout_p, 0) != enRspOK) { throw(QString("Error AgilentLan.CPP/Open TcpSocket Open Connection error")); } if (m_boDebug) { throw(QString("Tcp Socket is open")); } return boRet_l; } bool CAgilentLan::Close(const int iTimeout_p) { bool boRet_l = true; while(isRunning()); if (this->Execute("CloseConnection", 0, iTimeout_p, 0) != enRspOK) { throw(QString("Error AgilentLan.CPP/Close Connection error")); } if (m_boDebug) { throw(QString("Tcp Socket is closed")); } while(isRunning()); return boRet_l; } CAgilentLan::t_enRspType CAgilentLan::Execute(const char *strCmd_p, const int iWaitResponse_p, const int iTimeout_p, const int iRspDelayed_p) { CAgilentLan::t_enRspType enRetVal_l = enRspOffline; if (!isRunning()) { m_ByteArrayRead.clear(); m_ByteArrayWrite.clear(); m_ByteArrayWrite.append(strCmd_p); m_iWaitResponse = iWaitResponse_p; m_iTimeout = iTimeout_p; m_iResponseDelayed = iRspDelayed_p; start(); m_MtxProcess.lock(); m_WaitCondProcess.wait(&m_MtxProcess,-1); m_MtxProcess.unlock(); enRetVal_l = this->m_enRetVal; } else { enRetVal_l = enRspError; } while(isRunning()); return enRetVal_l; } QByteArray CAgilentLan::GetLastResponse(void) { QByteArray ay_l; m_MtxResponse.lock(); ay_l = m_ByteArrayRead; m_MtxResponse.unlock(); return ay_l; } void CAgilentLan::run() { bool boRun_l = true; bool boSent_l = false; const char *pStrCmd_l = NULL; const char *pStrRsp_l = NULL; m_enRetVal = enRspError; if (strcmp(m_ByteArrayWrite.data(),"CreateObject")==0) { if (this->m_boSimulate == true) { m_enRetVal = enRspOK; } else { m_pTcpSctCtrl = (QTcpSocket *)new QTcpSocket; if (m_pTcpSctCtrl != NULL) { m_enRetVal = enRspOK; } } boRun_l = false; } if (strcmp(m_ByteArrayWrite.data(),"DeleteObject")==0) { if (this->m_boSimulate == true) { } else { if (m_pTcpSctCtrl != NULL) { delete m_pTcpSctCtrl; } } m_enRetVal = enRspOK; boRun_l = false; } if (strcmp(m_ByteArrayWrite.data(),"OpenConnection")==0) { if (this->m_boSimulate == true) { m_enRetVal = enRspOK; } else { m_pTcpSctCtrl->connectToHost(m_strCtrlIP,5025); if (m_pTcpSctCtrl->waitForConnected(m_iTimeout) == true) { m_enRetVal = enRspOK; } } boRun_l = false; } if (strcmp(m_ByteArrayWrite.data(),"CloseConnection")==0) { if (this->m_boSimulate == true) { m_enRetVal = enRspOK; } else { m_pTcpSctCtrl->disconnectFromHost(); if ((m_pTcpSctCtrl->state() == QAbstractSocket::UnconnectedState) || (m_pTcpSctCtrl->waitForDisconnected(m_iTimeout))) { m_enRetVal = enRspOK; } } boRun_l = false; } int iTimeout_l = m_iTimeout; while (boRun_l && (!this->m_boSimulate)) { if (boSent_l == false) { boSent_l = true; // Kommando absetzen m_pTcpSctCtrl->write(m_ByteArrayWrite.data(),m_ByteArrayWrite.size()); // Auf Antwort warten if (m_iWaitResponse >= 0) { QThread::msleep(m_iWaitResponse); } else { boRun_l = false; } } // Anwort auf Kommando abwarten if ((m_pTcpSctCtrl->bytesAvailable() > 0) && (boRun_l == true)) { m_MtxResponse.lock(); m_ByteArrayRead.append(m_pTcpSctCtrl->readAll()); if (m_boDebug) { throw(QString(m_ByteArrayRead.data())); } m_MtxResponse.unlock(); iTimeout_l = m_iTimeout; // iTimeout_l = m_iWaitResponse; } else { if (m_pTcpSctCtrl->waitForReadyRead(iTimeout_l) == false) { m_MtxResponse.lock(); if (m_ByteArrayRead.size() == 0) { if (m_boDebug) { throw(QString("AgilentLan Timeout")); } m_enRetVal = enRspTimeout; } else { m_enRetVal = enRspOK; } m_MtxResponse.unlock(); boRun_l = false; } } } QThread::msleep(m_iResponseDelayed); QMutexLocker locker(&m_MtxProcess); m_WaitCondProcess.wakeOne(); }
This code section I have adapted to the following:
class CAgilentLan : public QObject { Q_OBJECT public: ... CAgilentLan(QString strIpAdress_p, int iTimeout_p, bool boSimulate_p=false, bool boDebug_p=false); ~CAgilentLan(); ... t_enRspType Execute(const char *strCmd_p, const int iWaitResponse_p, const int iTimeout_p, const int iRspDelayed_p); .. public slots: void init(); void openCommunikation(); void AgilentStart(); signals: void finished(); .... };
what is wrong?
-
How to use qthread with mutex?
Here is my old code:
Header:class QTcpSocket; class CAgilentLan : public QThread { public: typedef enum { enRspTimeout = -2, enRspOffline, enRspOK, enRspError } t_enRspType ; CAgilentLan(QString strIpAdress_p, int iTimeout_p, bool boSimulate_p=false, bool boDebug_p=false); ~CAgilentLan(); // High-Level Funktionen QByteArray ExecuteGetScreenshot(void); void ExecuteSaveScreenshot(QString &strPathFileName_p, const char *strFormat_p); void ExecuteSettingsSave(unsigned char ucRegisterNo_p); void ExecuteSettingsRecall(unsigned char ucRegisterNo_p); double ExecuteQuickMeasure(unsigned char ucChannel_p, char *pchType_p); double ExecuteStatMeasure(char *pchType_p, bool boTrigger_p); void ExecuteResetMeasurementStatistics(void); bool Open(const QString &strIpAdress_p, const int iTimeout_p); bool Close(const int iTimeout_p); t_enRspType Execute(const char *strCmd_p, const int iWaitResponse_p, const int iTimeout_p, const int iRspDelayed_p); QByteArray GetLastResponse(void); t_enRspType ExecuteSimulated(const char *strCmd_p); QString GetAgilentIdentifikation(); ... protected: void run(); private: bool m_boDebug; bool m_boSimulate; QMutex m_MtxProcess; QMutex m_MtxResponse; QWaitCondition m_WaitCondProcess; QByteArray m_ByteArrayWrite; QByteArray m_ByteArrayRead; QByteArray m_IDN_AgilentIdentification; //Hilfsvariable double m_SDDevPeriodeA ; double m_SDDevDCA; double m_SDDevDCB; double m_SDDevWidthZ; double m_OZiSDDevPeriodeA; double m_OZiSDDevDCA; double m_OZiSDDevDCB; double m_OZiSDDevWidthZ; double m_OZiMeanPeriodeA; double m_OZiMeanDCA; double m_OZiMeanDCB; double m_OZiMeanWidthZ; QByteArray m_ByteSTDD; QByteArray m_ByteMean; QStringList m_ListSTDDev; QStringList m_ListMean; QTcpSocket *m_pTcpSctCtrl; QString m_strCtrlIP; int m_iTimeoutClose; int m_iTimeout; int m_iResponseDelayed; int m_iWaitResponse; t_enRspType m_enRetVal; };
Cpp File:
CAgilentLan::CAgilentLan(QString strIpAdress_p, int iTimeout_p, bool boSimulate_p, bool boDebug_p):m_SDDevPeriodeA(0), m_SDDevDCA(0),m_SDDevDCB(0),m_SDDevWidthZ(0) { // boSimulate_p = false; m_boDebug = boDebug_p; m_boSimulate = boSimulate_p; m_enRetVal = enRspOffline; m_strCtrlIP = QString(""); m_iTimeout = 0; m_iTimeoutClose = iTimeout_p; if (this->Execute("CreateObject", 0, 0, 0) != enRspOK) { throw(QString("Error AgilentLan.CPP/Constructor TcpSocket Create memory error")); } this->Open(strIpAdress_p, iTimeout_p); } CAgilentLan::~CAgilentLan() { while(isRunning()); this->Close(m_iTimeoutClose); while(isRunning()); if (this->Execute("DeleteObject", 0, 0, 0) != enRspOK) { throw(QString("Error AgilentLan.CPP/Destructor TcpSocket Delete memory error")); } while(isRunning()); } bool CAgilentLan::Open(const QString &strCtrlIP_p, const int iTimeout_p) { bool boRet_l = true; m_strCtrlIP = strCtrlIP_p; if (this->Execute("OpenConnection", 0, iTimeout_p, 0) != enRspOK) { throw(QString("Error AgilentLan.CPP/Open TcpSocket Open Connection error")); } if (m_boDebug) { throw(QString("Tcp Socket is open")); } return boRet_l; } bool CAgilentLan::Close(const int iTimeout_p) { bool boRet_l = true; while(isRunning()); if (this->Execute("CloseConnection", 0, iTimeout_p, 0) != enRspOK) { throw(QString("Error AgilentLan.CPP/Close Connection error")); } if (m_boDebug) { throw(QString("Tcp Socket is closed")); } while(isRunning()); return boRet_l; } CAgilentLan::t_enRspType CAgilentLan::Execute(const char *strCmd_p, const int iWaitResponse_p, const int iTimeout_p, const int iRspDelayed_p) { CAgilentLan::t_enRspType enRetVal_l = enRspOffline; if (!isRunning()) { m_ByteArrayRead.clear(); m_ByteArrayWrite.clear(); m_ByteArrayWrite.append(strCmd_p); m_iWaitResponse = iWaitResponse_p; m_iTimeout = iTimeout_p; m_iResponseDelayed = iRspDelayed_p; start(); m_MtxProcess.lock(); m_WaitCondProcess.wait(&m_MtxProcess,-1); m_MtxProcess.unlock(); enRetVal_l = this->m_enRetVal; } else { enRetVal_l = enRspError; } while(isRunning()); return enRetVal_l; } QByteArray CAgilentLan::GetLastResponse(void) { QByteArray ay_l; m_MtxResponse.lock(); ay_l = m_ByteArrayRead; m_MtxResponse.unlock(); return ay_l; } void CAgilentLan::run() { bool boRun_l = true; bool boSent_l = false; const char *pStrCmd_l = NULL; const char *pStrRsp_l = NULL; m_enRetVal = enRspError; if (strcmp(m_ByteArrayWrite.data(),"CreateObject")==0) { if (this->m_boSimulate == true) { m_enRetVal = enRspOK; } else { m_pTcpSctCtrl = (QTcpSocket *)new QTcpSocket; if (m_pTcpSctCtrl != NULL) { m_enRetVal = enRspOK; } } boRun_l = false; } if (strcmp(m_ByteArrayWrite.data(),"DeleteObject")==0) { if (this->m_boSimulate == true) { } else { if (m_pTcpSctCtrl != NULL) { delete m_pTcpSctCtrl; } } m_enRetVal = enRspOK; boRun_l = false; } if (strcmp(m_ByteArrayWrite.data(),"OpenConnection")==0) { if (this->m_boSimulate == true) { m_enRetVal = enRspOK; } else { m_pTcpSctCtrl->connectToHost(m_strCtrlIP,5025); if (m_pTcpSctCtrl->waitForConnected(m_iTimeout) == true) { m_enRetVal = enRspOK; } } boRun_l = false; } if (strcmp(m_ByteArrayWrite.data(),"CloseConnection")==0) { if (this->m_boSimulate == true) { m_enRetVal = enRspOK; } else { m_pTcpSctCtrl->disconnectFromHost(); if ((m_pTcpSctCtrl->state() == QAbstractSocket::UnconnectedState) || (m_pTcpSctCtrl->waitForDisconnected(m_iTimeout))) { m_enRetVal = enRspOK; } } boRun_l = false; } int iTimeout_l = m_iTimeout; while (boRun_l && (!this->m_boSimulate)) { if (boSent_l == false) { boSent_l = true; // Kommando absetzen m_pTcpSctCtrl->write(m_ByteArrayWrite.data(),m_ByteArrayWrite.size()); // Auf Antwort warten if (m_iWaitResponse >= 0) { QThread::msleep(m_iWaitResponse); } else { boRun_l = false; } } // Anwort auf Kommando abwarten if ((m_pTcpSctCtrl->bytesAvailable() > 0) && (boRun_l == true)) { m_MtxResponse.lock(); m_ByteArrayRead.append(m_pTcpSctCtrl->readAll()); if (m_boDebug) { throw(QString(m_ByteArrayRead.data())); } m_MtxResponse.unlock(); iTimeout_l = m_iTimeout; // iTimeout_l = m_iWaitResponse; } else { if (m_pTcpSctCtrl->waitForReadyRead(iTimeout_l) == false) { m_MtxResponse.lock(); if (m_ByteArrayRead.size() == 0) { if (m_boDebug) { throw(QString("AgilentLan Timeout")); } m_enRetVal = enRspTimeout; } else { m_enRetVal = enRspOK; } m_MtxResponse.unlock(); boRun_l = false; } } } QThread::msleep(m_iResponseDelayed); QMutexLocker locker(&m_MtxProcess); m_WaitCondProcess.wakeOne(); }
This code section I have adapted to the following:
class CAgilentLan : public QObject { Q_OBJECT public: ... CAgilentLan(QString strIpAdress_p, int iTimeout_p, bool boSimulate_p=false, bool boDebug_p=false); ~CAgilentLan(); ... t_enRspType Execute(const char *strCmd_p, const int iWaitResponse_p, const int iTimeout_p, const int iRspDelayed_p); .. public slots: void init(); void openCommunikation(); void AgilentStart(); signals: void finished(); .... };
what is wrong?
@Galilio This can be simplified:
QByteArray CAgilentLan::GetLastResponse(void) { QByteArray ay_l; m_MtxResponse.lock(); ay_l = m_ByteArrayRead; m_MtxResponse.unlock(); return ay_l; }
to
QByteArray CAgilentLan::GetLastResponse(void) { QMutexLocker(m_MtxResponse); return m_ByteArrayRead; }
-
At a class where I have the object "CAgilentLan"
Calls I write in the contructor the following://CAgilentLan* m_pvAgilentWorker; m_pvWorkerThread = new QThread(); m_pvAgilentWorker = new CAgilentLan(settings_l.strfuGetIP_DSO(), 500, settings_l.bofuGetSimulate()); m_pvAgilentWorker->moveToThread(m_pvWorkerThread); connect(m_pvWorkerThread, &QThread::started, m_pvAgilentWorker, &CAgilentLan::agilentStart); connect(m_pvWorkerThread, &QThread::finished, m_pvWorkerThread, &QThread::deleteLater); connect(m_pvWorkerThread, &QThread::finished, m_pvWorkerThread, &CAgilentLan::deleteLater); m_pvWorkerThread->start();
This is the error message:
ASSERT failure in QCoreApplication::sendEvent: "Cannot send events to objects owned by a different thread. Current thread 4c19f68. Receiver '' (of type 'QNativeSocketEngine') was created in thread 4c582e0", file kernel\qcoreapplication.cpp, line 541
-
@Galilio This can be simplified:
QByteArray CAgilentLan::GetLastResponse(void) { QByteArray ay_l; m_MtxResponse.lock(); ay_l = m_ByteArrayRead; m_MtxResponse.unlock(); return ay_l; }
to
QByteArray CAgilentLan::GetLastResponse(void) { QMutexLocker(m_MtxResponse); return m_ByteArrayRead; }
QByteArray CAgilentLan::GetLastResponse(void) { QMutexLocker(m_MtxResponse); return m_ByteArrayRead; }
Won't that temporary QMutexLocker need a name? Otherwise it will be deconstructed as a temporary object at the end of the first statement and the return won't be locked properly.
-
QByteArray CAgilentLan::GetLastResponse(void) { QMutexLocker(m_MtxResponse); return m_ByteArrayRead; }
Won't that temporary QMutexLocker need a name? Otherwise it will be deconstructed as a temporary object at the end of the first statement and the return won't be locked properly.
@corruptedsyntax Sure, thanks for pointing that out :-)
QByteArray CAgilentLan::GetLastResponse(void) { QMutexLocker mutexLocker(m_MtxResponse); return m_ByteArrayRead; }
-
@corruptedsyntax Sure, thanks for pointing that out :-)
QByteArray CAgilentLan::GetLastResponse(void) { QMutexLocker mutexLocker(m_MtxResponse); return m_ByteArrayRead; }
-
@jsulm
Hi,
So is correct:QByteArray CAgilentLan::GetLastResponse(void) { QMutexLocker mutexLocker(&m_MtxResponse); return m_ByteArrayRead; }
-
@jsulm
Problem occurs when the application is exited.
The Destructor is then called, which looks like this:CAgilentLan::~CAgilentLan() { this->Close(GetiTimeOutClose()); if (this->Execute("DeleteObject", 0, 0, 0) != enRspOK) { throw(QString("Error AgilentLan.CPP/Destructor TcpSocket Delete memory error")); } }
And right here is the problem:
GetTcpSocket()->disconnectFromHost();
-
@jsulm
Problem occurs when the application is exited.
The Destructor is then called, which looks like this:CAgilentLan::~CAgilentLan() { this->Close(GetiTimeOutClose()); if (this->Execute("DeleteObject", 0, 0, 0) != enRspOK) { throw(QString("Error AgilentLan.CPP/Destructor TcpSocket Delete memory error")); } }
And right here is the problem:
GetTcpSocket()->disconnectFromHost();
-
@Galilio What error? What problem? Can you be more precise?
You should not throw exceptions from destructors.@jsulm
The TcpSocket connection can not be closed
Error is:ASSERT failure in QCoreApplication::sendEvent: "Cannot send events to objects owned by a different thread. Current thread dc02d0. Receiver '' (of type 'QNativeSocketEngine') was created in thread 4912418", file kernel\qcoreapplication.cpp, line 541
-
@jsulm
The TcpSocket connection can not be closed
Error is:ASSERT failure in QCoreApplication::sendEvent: "Cannot send events to objects owned by a different thread. Current thread dc02d0. Receiver '' (of type 'QNativeSocketEngine') was created in thread 4912418", file kernel\qcoreapplication.cpp, line 541
-
@jsulm
Yes but what?
My QThread looks like this:m_pvWorkerThread = new QThread(); m_pvAgilentWorker = new CAgilentLan(settings_l.strfuGetIP_DSO(), 500, settings_l.bofuGetSimulate()); m_pvAgilentWorker->moveToThread(m_pvWorkerThread); connect(m_pvWorkerThread, &QThread::started, m_pvAgilentWorker, &CAgilentLan::agilentStart); connect(m_pvWorkerThread, &QThread::finished, m_pvWorkerThread, &QThread::deleteLater); connect(m_pvWorkerThread, &QThread::finished, m_pvWorkerThread, &CAgilentLan::deleteLater); m_pvWorkerThread->start();
-
@jsulm
Yes but what?
My QThread looks like this:m_pvWorkerThread = new QThread(); m_pvAgilentWorker = new CAgilentLan(settings_l.strfuGetIP_DSO(), 500, settings_l.bofuGetSimulate()); m_pvAgilentWorker->moveToThread(m_pvWorkerThread); connect(m_pvWorkerThread, &QThread::started, m_pvAgilentWorker, &CAgilentLan::agilentStart); connect(m_pvWorkerThread, &QThread::finished, m_pvWorkerThread, &QThread::deleteLater); connect(m_pvWorkerThread, &QThread::finished, m_pvWorkerThread, &CAgilentLan::deleteLater); m_pvWorkerThread->start();
@Galilio Sorry, currently I have no time to analyse your code.
You should read: https://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/