在Qt中,是否可以从2个不同的线程同时读取和写入同一个串行端口?使用2个线程在串行端口上同时读写
回答
不是。由于它的实现,不可能从不同的线程读取/写入(与Qt的任何I/O类相同)。 QSP使用允许使用“同时”从一个线程读取/写入的非阻塞(异步)I/O。
不是直接。您致电port
的任何方法都必须在port.thread()
内调用。否则是未定义的行为:您可能会格式化您的硬盘驱动器。
但您可以通过使用信号插槽机制间接地完成。而不是调用该端口的方法,让我们充当一个线程安全的接口端口的接口类:
struct PortInterface : QObject {
Q_SIGNAL void writeData(const QByteArray &);
Q_SIGNAL void hasReadData(const QByteArray &);
Q_OBJECT
};
int main(int argc, char ** argv) {
QApplication app(argc, argv);
PortInterface interface;
QSerialPort port;
QObject::connect(&interface, &PortInterface::writeData, &port, [&](const QByteArray &data){
qDebug() << "writing in thread" << QThread::currentThread();
Q_ASSERT(QThread::currentThread() == port.thread());
port.write(data);
});
QObject::connect(&port, &QIODevice::readyRead, [&]{
qDebug() << "reading in thread" << QThread::currentThread();
Q_ASSERT(QThread::currentThread() == port.thread());
emit interface.hasReadData(port.readAll());
});
你可以调用任何线程中writeData
方法:Qt的信号槽机制将包裹该电话并将其安全地交付给港口的线程。同样,可以从任何线程调用hasReadData
信号。 readAll
调用是从端口自己的线程完成的。处理可用数据的代码应连接到该插槽。
因此,我们可以在一个专用线程蜱一些数据写入端口定时器,我们可以监听到新的数据在主线程插槽:
QTimer sourceTimer;
sourceTimer.start(20);
QObject::connect(&sourceTimer, &QTimer::timeout, [&]{
qDebug() << "timer tick in thread" << QThread::currentThread();
interface.writeData(QByteArray(20, 'd'));
});
QObject::connect(&interface, &PortInterface::hasReadData, &app, [&](const QByteArray &data){
qDebug() << "data read in thread" << QThread::currentThread();
qDebug() << data.toHex();
});
QThread sourceThread, portThread;
QThread::currentThread()->setObjectName("mainThread");
sourceThread.setObjectName("sourceThread");
portThread.setObjectName("portThread");;
sourceTimer.moveToThread(&sourceThread);
port.moveToThread(&portThread);
sourceThread.start();
portThread.start();
return app.exec();
}
你可以有任何数量的对象附加到hasReadData
信号。这些对象可以存在于任何线程中。回想一下,信号插槽连接是1:n
种,其中0<=n
。同样,你可以有任意数量的对象调用接口的writeData
方法:只要他们写的数据是一个自包含的数据包,就可以保证数据包将在端口上作为单位,而不与其他数据包交织。但是,接收方必须能够描述分组,但是分组需要头部或其他同步手段(例如HDLC)。
当然,您需要先打开端口:)
你能帮我安排这个代码到一个Qt项目中吗?至于上面哪段代码去哪里? – Aham
@Aham想象一下散文(描述文本)不在那里。把代码片段粘在一起,你会得到一个可以编译的'main.cpp'。它不会做太多的事情,因为这个端口没有打开,但是它完成了。 –
- 1. 同步串行端口读取/写入
- 2. 如何使用线程读取和写入串行端口上的数据
- 3. 如何使用2个线程同时读取/写入文件?
- 4. 如何在Windows上使用Java读取/写入串行端口?
- 5. 在Arduino上写入和读取多个串行端口
- 6. pyserial - 可能从线程写入串行端口a,阻塞读取线程b?
- 7. 在同一个COM端口上使用两个串行端口 - WPF C#
- 8. 同一端口上的2个进程?
- 9. 从串行端口写入和读取
- 10. Win32,串行端口读/写和重叠
- 11. Java:使用Java.util.concurrent线程访问线程化串行端口
- 12. 在同一个端口上的2个应用程序
- 13. 写串行端口在Linux
- 14. Python多线程/多进程读取串行端口
- 15. 使用C++读取和写入串行端口
- 16. 如何使用Qextserialport在串行端口上写入
- 17. C++串行端口仅在使用写入时才响应
- 18. 同时运行2个线程
- 19. c#同时执行2个线程
- 20. 使用2个不同的IP在端口80上运行2个应用程序
- 21. 使用node.js在2个不同的端口上侦听
- 22. ObjectDisposedException当我放弃正在写入串行端口的线程时
- 23. 在Main中使用从多个串行端口读取数据()
- 24. 一个写线程,一个读线程在同一个套接字上?
- 25. 使用USB连接串行连接器读取和写入串行端口COM3
- 26. 串行端口异步读取(非阻塞)+线程
- 27. C#+线程+串行端口+锁
- 28. 多线程的串行端口C#
- 29. 串行端口和多线程问题
- 30. 多线程和侦听串行端口
不,但无论如何,您认为您需要这样做很可能是错误的。当然,数据可以来自任何你想要的地方,但是'QSerialPort'方法的调用必须全部使用与'port-> thread()'相同的线程来完成。 –
@Kuba Ober,我明白你的意思。但这是问题。我试图演示在一个线程上读取串行端口并在GUI线程上显示。为了测试,我需要不断写入串口,同时需要从串口读取相同的数据并显示在GUI线程中。我试图在一台机器上展示所有这些(我的笔记本电脑)。所以我想我的应用程序中有3个线程。 1个主GUI线程,1个读取器线程,1个写入器线程。 – Aham
阅读器和书写器必须是相同的线程。鉴于串行端口的速度相对于CPU /内存带宽相对较低,将作业拆分为两个线程会使情况变得更糟,而不是更好:具有多个线程的开销高于保持串行端口塞入所需的工作量随时提供数据,并处理任何答复。 –