読み取り操作用のブロックなしモードとブロック モードを持つ C++ シリアル ポート クラスがあります。ブロッキング モードの場合:
COMMTIMEOUTS cto;
GetCommTimeouts(m_hFile,&cto);
// Set the new timeouts
cto.ReadIntervalTimeout = 0;
cto.ReadTotalTimeoutConstant = 0;
cto.ReadTotalTimeoutMultiplier = 0;
SetCommTimeouts(m_hFile,&cto)
非ブロッキング モードの場合:
COMMTIMEOUTS cto;
GetCommTimeouts(m_hFile,&cto);
// Set the new timeouts
cto.ReadIntervalTimeout = MAXDWORD;
cto.ReadTotalTimeoutConstant = 0;
cto.ReadTotalTimeoutMultiplier = 0;
SetCommTimeouts(m_hFile,&cto)
任意のバイト数を待機して読み取る別のモードを追加したいと思います。
MSDN COMMTIMEOUTS 構造体から:
アプリケーションがReadIntervalTimeoutとReadTotalTimeoutMultiplierをMAXDWORDに設定し、 ReadTotalTimeoutConstantを 0 より大きくMAXDWORDより小さい値に設定した場合、ReadFile 関数が呼び出されると、次のいずれかが発生します。
- 入力バッファーにバイトがある場合、ReadFile はバッファー内のバイトと共にすぐに戻ります。
- 入力バッファーにバイトがない場合、ReadFile はバイトが到着するまで待機し、すぐに戻ります。
- ReadTotalTimeoutConstant で指定された時間内にバイトが到着しない場合、ReadFile はタイムアウトになります。
これは、次のようなコードになります。
COMMTIMEOUTS cto;
GetCommTimeouts(m_hFile,&cto);
// Set the new timeouts
cto.ReadIntervalTimeout = 100;
cto.ReadTotalTimeoutConstant = MAXDWORD;
cto.ReadTotalTimeoutMultiplier = MAXDWORD;
SetCommTimeouts(m_hFile,&cto)
しかし、これは最初のバイトに偏って戻ります。ポートをループで読み取っていて、バイトの処理が非常に高速であるため、次にポートを読み取ったときに別のバイトしか使用できないため、これは問題です。最終結果は、ループで一度に 1 バイトを読み取り、そのスレッドを実行しているコアの 100% を使用していることです。
MSDN ドキュメントでlike を使用したいのですがcto.ReadIntervalTimeout
、少なくとも 1 バイトが利用可能になるまで待ちます。誰にもアイデアはありますか?
ありがとう。