Qtでは、2つの異なるスレッドから同じシリアルポートを同時に読み書きすることはできますか?2つのスレッドを使ってシリアルポートを同時に読み書きする
答えて
インプリメンテーションのために異なるスレッドから読み書きすることはできません(QtのI/Oクラスと同じ)。 QSPは、非同期(非同期)I/Oを使用します。これにより、1つのスレッドからの読み込み/書き込みを「同時」に使用できます。
直接ではありません。 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つのスレッドによるファイルの同時読み込み/書き込み
- 2. Linux Cシリアルポート読み書き
- 3. シリアルポートを開いて読み書きする最大スレッド数MOXA NPort
- 4. 同時にシリアルポートに書き込んで読み込む方法は?
- 5. StreamWriterでTextWriterを同時に使用して読み込み/書き込みを同時に実行する
- 6. Node.jsを使用して書き込み後にシリアルポートを読み取る
- 7. android java異なるスレッドから同時にテキストビューを読み書きします。
- 8. シリアルポートの読み書き方法
- 9. 書き込み中に同時にcassandraを読み取る
- 10. 2つのスレッドが同じ組み込みPythonインタプリタを同時に使用できますか?
- 11. ファイルを2つのスレッドで同時に使用する
- 12. 2つのストリームに同時に書き込み
- 13. C#のシリアルポートとの間でデータを読み書きする
- 14. シリアルポート非同期読み取り(非ブロッキング)+スレッド
- 15. Java - 同時にファイルを読み書きするには?
- 16. Couchbase読み書き同時実行
- 17. Ruby StringIO同時読み書き用
- 18. Javaコンソール/読み書き同時実行
- 19. 同時に変数を読み書きする
- 20. PythonとCファイルを同時に読み書きする
- 21. Javaでファイルを同時に読み書きする
- 22. 同じCOMポートに2つのシリアルポートを使用する - WPF C#
- 23. Qtを使って同時実行スレッド
- 24. 誰かがQSockeNotifier(Qtライブラリ)を使ってLinuxのシリアルポートを読み書きしていますか?
- 25. ソケットの読み込みと書き込みを同時に実行する
- 26. commons.io.FileUtilsを使ってdocxファイルを読み書きするには?
- 27. 2つのプログラムでテキストファイルを同時に読み書きすることは可能ですか
- 28. シリアルポートの書き込みが成功し、読み込みに失敗する
- 29. 2つのスレッドを使用してテキストボックスに書き込む
- 30. Pythonマルチプロセッシングを使ったファイルの同時書き込み
ありませんが、あなたはそれが誤りで最も可能性が高いです行う必要があると思わせるものは何でも。もちろん、データはどこからでも得ることができますが、 'QSerialPort'メソッドの呼び出しはすべて' port-> thread() 'と同じスレッドから行わなければなりません。 –
@Kuba Ober、私はあなたを得る。しかし、ここに問題があります。あるスレッドでシリアルポートを読み取ってGUIスレッドで表示することをデモしようとしています。これをテストするために、私はシリアルポートに連続的に書き込む必要があり、同時に同じデータをシリアルポートから読み込んでGUIスレッドに表示する必要があります。そして、私はこれをすべて一つのマシン(私のラップトップ)で実証しようとしています。だから私は私のアプリケーションで3スレッドを持つことを考えた。 1つのメインGUIスレッド、1つのリーダースレッド、1つのライタースレッド。 – Aham
リーダーとライターは同じスレッドでなければなりません。シリアルポートの速度がCPU /メモリの帯域幅と比較して相対的に遅いことを考えると、ジョブを2つのスレッドに分割すると、パフォーマンスは悪くなく良くなります。複数のスレッドを持つオーバーヘッドは、シリアルポートを詰め込むいつでもデータを持ち、返答を処理することができます。 –