在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 /內存帶寬相對較低,將作業拆分爲兩個線程會使情況變得更糟,而不是更好:具有多個線程的開銷高於保持串行端口塞入所需的工作量隨時提供數據,並處理任何答覆。 –