在QRunnable中调用QEventLoop(连接到多个设备)

时间:2015-12-02 15:13:43

标签: c++ multithreading qt threadpool qeventloop

我有一个QthreadPool可以同时连接多达5个串行设备。每个串行设备定义为:

struct serialDevice
{
    std::shared_ptr<QSerialPort>  port;
    QByteArray                    portData;
};

在GUI内部,点击按钮后,我按如下方式呼叫串行设备管理器serialManager->startAcquisition(portNames)

#include "serialmanager.h"
serialManager::serialManager(QObject *parent) : QObject(parent)
{
    pool = new QThreadPool();
    pool->setMaxThreadCount(5);
}

void serialManager::startAcquisition(QStringList pNames)
{
    foreach (QString port, pNames)
    {
        this->stablishConnection(port);
    }
}

void serialManager::stablishConnection(QString pName)
{
    ComPort *workerPort = new ComPort();
    workerPort->setAutoDelete(true);
    workerPort->setName(pName);

    connect(this, SIGNAL(finished()), workerPort, SLOT(onTaskeFinished()));

    pool->start(workerPort);
}

连接设备后,我会轮询设备。调用stop函数时,线程终止。 我希望发出readyRead()信号,以填充sensor->portData

#include "serialmanager.h"
#include <QEventLoop>

ComPort::ComPort(QObject *parent) : QObject(parent)
{
}

void ComPort::run()
{
    QEventLoop loop;
    connect(this, SIGNAL(finished()), &loop, SLOT(quit()));

    sensor       = std::make_shared<serialDevice> ();
    sensor->port = std::make_shared<QSerialPort> ();
    sensor->port->setPortName(this->portName);
    sensor->port->setBaudRate(QSerialPort::Baud19200);
    sensor->port->setDataBits(QSerialPort::Data8);
    sensor->port->setFlowControl(QSerialPort::NoFlowControl);
    sensor->port->setParity(QSerialPort::NoParity);
    sensor->port->setStopBits(QSerialPort::OneStop);

    QString strPort;
    if (sensor->port->open(QIODevice::ReadWrite) == true)
    {
        connect(sensor->port.get(), SIGNAL(error(QSerialPort::SerialPortError)), this, SLOT(onErrorReceived()));
        connect(sensor->port.get(), SIGNAL(readyRead()), this, SLOT(onReadyRead()));
    }
    else
    {
        strPort = "> " + sensor->port->portName() + " device is not streaming: " + sensor->port->errorString();
        emit this->newMsgAvailable(strPort);
        emit this->finished();
    }
    loop.exec();
}

void ComPort::onReadyRead()
{
    QByteArray bytes = this->sensor->port->readAll();
    this->sensor->portData.append(bytes);
}

void ComPort::onTaskeFinished()
{
    QString strPort = "> Finished streaming at " + sensor->port->portName();
    emit newMsgAvailable(strPort);
    emit this->finished();
}

void ComPort::onErrorReceived()
{
    QString strPort = "> Data stream on "  + sensor->port->portName() + " failed: " + sensor->port->errorString();
    emit newMsgAvailable(strPort);
}

问题定义: 未发出readyRead()信号。 I have read here,要处理QRunnable中的事件,线程需要有自己的事件循环。因此,我将QEventLoop loop包含在每个Run()的{​​{1}}函数中。现在ComPort被触发,我从每个端口接收数据一段时间,然后突然应用程序因分段故障而崩溃:

readyRead()

0 个答案:

没有答案