Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/138.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在QRunnable中调用QEventLoop(连接到多个设备)_C++_Multithreading_Qt_Threadpool_Qeventloop - Fatal编程技术网

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

C++ 在QRunnable中调用QEventLoop(连接到多个设备),c++,multithreading,qt,threadpool,qeventloop,C++,Multithreading,Qt,Threadpool,Qeventloop,我有一个QthreadPool,可以同时连接多达5个串行设备。每个串行设备定义为: struct serialDevice { std::shared_ptr<QSerialPort> port; QByteArray portData; }; 连接设备后,我轮询该设备。当调用停止函数时,线程终止。 我希望发出readyRead()信号,以便填充传感器->端口数据的内部: #include "serialmanager.h"

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

struct serialDevice
{
    std::shared_ptr<QSerialPort>  port;
    QByteArray                    portData;
};
连接设备后,我轮询该设备。当调用停止函数时,线程终止。 我希望发出
readyRead()
信号,以便填充
传感器->端口数据的内部:

#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);
}

在没有看到更多代码的情况下回答您的问题是不可能的。我质疑多线程用于多个串行连接;您不需要使用阻塞
QRunnable
。只需将所有串行端口塞入一个专用的
QThread
。确保你的代码没有阻塞,你会没事的。如果需要基于串行数据进行大量计算,请使用
QtConcurrent::run
,它将自动分布在全局池的线程中。例如,有关异步数据处理的灵感,请参见。@Kuba我使用了
QThreadPool
,因为我不知道如何处理同一
QThread
中多个串行对象的
readyRead()
。您能给我一个如何在一个线程中实现它的示例吗?您将插槽连接到一个特定的
QSerialPort
实例-这些线程在您的
connect
调用中的任何位置都不会出现。这是一个最简单的例子:
{QSerialPort a,b;a.connect(&a,&QSerialPort::readyRead,[]{qDebug()一个简单的方法是使用一个封装端口和设备协议的
QObject
。它不知道自身的任何其他实例,因此“问题”存在多个实例不会有问题。您可以将此对象的所有实例移动到专用线程:
{QApplication app(…);CommHandler a,b,c;thread;a.open(“portname”);b.open(“portname”);c.open(“portname”);a.moveToThread(&thread);b.moveToThread(&thread);c.moveToThread(&thread);return app.exec()}
@Kuba感谢您提供的示例。如果我无法调用主线程中的
ComHandler
对象(例如,它们位于主窗口实例中),我应该如何定义
QEventLoop
及其
exec()
#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);
}
0   VerifierDisableFaultInjectionExclusionRange C:\WINDOWS\syswow64\verifier.dll                0x53457378  
1   VerifierDisableFaultInjectionExclusionRange C:\WINDOWS\syswow64\verifier.dll                0x53457495  
2   VerifierDisableFaultInjectionExclusionRange C:\WINDOWS\syswow64\verifier.dll                0x5345b651  
3   VerifierCheckPageHeapAllocation             C:\WINDOWS\syswow64\verifier.dll                0x53460b12  
4   ??                                          C:\WINDOWS\SysWOW64\vfbasics.dll                0x533d179f  
5   msvcrt!free                                 C:\WINDOWS\SysWOW64\msvcrt.dll                  0x7509b0f9  
6   ??                                                                                          0x19120000  
7   ??                                          C:\WINDOWS\SysWOW64\vfbasics.dll                0x533d26a5  
8   QArrayData::deallocate                                                              130 
9   QTypedArrayData<char>::deallocate                                                   234     0x6b9cbcfd  
10  QByteArray::resize                                                                  1448    0x6b79bc23  
11  QRingBuffer::append                                                                 383     0x645893ae  
12  QSerialPortPrivate::_q_completeAsyncRead                                            529     0x6458523f  
13  QSerialPort::qt_static_metacall                                                     353     0x64582dae  
14  QMetaObject::activate                                                               3681    0x6b955027  
15  QMetaObject::activate                                                               3547    0x6b95498c  
16  QWinEventNotifier::activated                                                        134     0x6b9ad529  
17  QWinEventNotifier::event                                                            241     0x6b976af1  
18  QApplicationPrivate::notify_helper                                                  3499    0xf33df61   
19  QApplication::notify                                                                2952    0xf33ba13   
20  QCoreApplication::notifyInternal                                                    935     0x6b929eee  
... <More>