I am creating a multithreade application to read from multiple serial devices at a time and send data to a network. My application works but I am not sure about how to perfectly use mutex in my application.
My application crashes sometimes, So I used QMutex to solve the issue.
My code is given
I created a static mutex object
{
Q_OBJECT
public:
explicit MyApp
(QObject *parent
= 0);
~MyApp();
static int s_iCount;
static QList<QString> s_resultList;
static bool s_bStopThreadFlag;
SerialDevice *objDevice;
QThreadEx *objDeviceThread;
void removeDeviceConnction();
void startDeviceReading();
signals:
void exitThread();
void sendInstructionToDevice
(QString strInstructions
);
private:
};
m_iDeviceReadingInterval(1000)
{
// m_mutex.lock();
s_iCount = 0;
s_bStopThreadFlag = false;
// m_mutex.unlock();
startDeviceReading();
// timerSendDataDelay->start();
}
void MyApp::startDeviceReading()
{
QList<QextPortInfo> portlist = portinfo.getPorts();
for(int iCount = 0; iCount < portlist.count(); iCount++)
{
objDeviceThread= new QThreadEx();
objDevice = new SerialDevice(portlist[iCount].portName, 0);
objDevice->setReadingInterval(m_iDeviceReadingInterval);
connect(this, SIGNAL(exitThread()), objDevice, SLOT(finishWork()));
connect(this, SIGNAL(setReadingInterval(int)), objDevice, SLOT(setReadingInterval(int)));
connect(this,
SIGNAL(sendInstructionToDevice
(QString)), objDevice,
SLOT(sendInstructionToDevice
(QString)));
connect(this, SIGNAL(startReadingTimer()), objDevice, SLOT(startReadingTimer()));
objDevice->m_strPortName = portlist[iCount].portName;
objDevice->connect(objDeviceThread,
SIGNAL(started()),
SLOT(produce()));
objDevice->moveToThread(objDeviceThread);
objDeviceThread->start();
}
}
class MyApp : public QObject
{
Q_OBJECT
public:
explicit MyApp(QObject *parent = 0);
~MyApp();
static int s_iCount;
static QList<QString> s_resultList;
static bool s_bStopThreadFlag;
static QMutex m_mutex;
SerialDevice *objDevice;
QThreadEx *objDeviceThread;
void removeDeviceConnction();
void startDeviceReading();
signals:
void exitThread();
void sendInstructionToDevice(QString strInstructions);
private:
QString m_strResultFull;
};
MyApp::MyApp(QObject *parent) :
QObject(parent),
m_iDeviceReadingInterval(1000)
{
// m_mutex.lock();
s_iCount = 0;
s_bStopThreadFlag = false;
// m_mutex.unlock();
startDeviceReading();
// timerSendDataDelay->start();
}
void MyApp::startDeviceReading()
{
QList<QextPortInfo> portlist = portinfo.getPorts();
for(int iCount = 0; iCount < portlist.count(); iCount++)
{
objDeviceThread= new QThreadEx();
objDevice = new SerialDevice(portlist[iCount].portName, 0);
objDevice->setReadingInterval(m_iDeviceReadingInterval);
connect(this, SIGNAL(exitThread()), objDevice, SLOT(finishWork()));
connect(this, SIGNAL(setReadingInterval(int)), objDevice, SLOT(setReadingInterval(int)));
connect(this, SIGNAL(sendInstructionToDevice(QString)), objDevice, SLOT(sendInstructionToDevice(QString)));
connect(this, SIGNAL(startReadingTimer()), objDevice, SLOT(startReadingTimer()));
objDevice->m_strPortName = portlist[iCount].portName;
objDevice->connect(objDeviceThread,
SIGNAL(started()),
SLOT(produce()));
objDevice->moveToThread(objDeviceThread);
objDeviceThread->start();
}
}
To copy to clipboard, switch view to plain text mode
Created the thred object and started the thred
And in my serial device class accesses the static variables and static mutex like this
void SerialDevice::produce()
{
// MyApp::m_mutex.lock();
MyApp::s_iCount++;
m_iThredCount = MyApp::s_iCount;
MyApp::s_resultList.append("null");
MyApp::s_ValueList.append("null");
//MyApp::m_mutex.unlock();
PortSettings settings = {BAUD19200, DATA_8, PAR_NONE, STOP_1, FLOW_OFF, 10};
m_port = new QextSerialPort(m_strPortName, settings, QextSerialPort::EventDriven);
timer->setInterval(20);
m_pagevalue = new char[20];
connect(timer, SIGNAL(timeout()), SLOT(onReadyRead()));
connect(m_port, SIGNAL(readyRead()), SLOT(onReadyRead()));
if (!m_port->isOpen())
{
m_port->setPortName(m_strPortName);
}
if (m_port->isOpen() && m_port->queryMode() == QextSerialPort::Polling)
timer->start();
else
timer->stop();
}
void SerialDevice::onReadyRead()
{
m_strData = "";
if (m_port->bytesAvailable())
{
m_strData = m_port->readAll();
// MyApp::m_mutex.lock();
MyApp::s_ValueList.replace(m_iThredCount - 1, strReadings);
// MyApp::m_mutex.unlock();
}
}
void SerialDevice::produce()
{
// MyApp::m_mutex.lock();
MyApp::s_iCount++;
m_iThredCount = MyApp::s_iCount;
MyApp::s_resultList.append("null");
MyApp::s_ValueList.append("null");
//MyApp::m_mutex.unlock();
PortSettings settings = {BAUD19200, DATA_8, PAR_NONE, STOP_1, FLOW_OFF, 10};
m_port = new QextSerialPort(m_strPortName, settings, QextSerialPort::EventDriven);
timer = new QTimer(this);
timer->setInterval(20);
m_pagevalue = new char[20];
connect(timer, SIGNAL(timeout()), SLOT(onReadyRead()));
connect(m_port, SIGNAL(readyRead()), SLOT(onReadyRead()));
if (!m_port->isOpen())
{
m_port->setPortName(m_strPortName);
m_port->open(QIODevice::ReadWrite);
}
if (m_port->isOpen() && m_port->queryMode() == QextSerialPort::Polling)
timer->start();
else
timer->stop();
}
void SerialDevice::onReadyRead()
{
m_strData = "";
if (m_port->bytesAvailable())
{
m_strData = m_port->readAll();
// MyApp::m_mutex.lock();
MyApp::s_ValueList.replace(m_iThredCount - 1, strReadings);
// MyApp::m_mutex.unlock();
}
}
To copy to clipboard, switch view to plain text mode
Bookmarks