C++ 在QRunnable中调用QEventLoop(连接到多个设备)
我有一个QthreadPool,可以同时连接多达5个串行设备。每个串行设备定义为: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"
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>