3

読み取り操作用のブロックなしモードとブロック モードを持つ 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 構造体から:

アプリケーションがReadIntervalTimeoutReadTotalTimeoutMultiplierMAXDWORDに設定し、 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 バイトが利用可能になるまで待ちます。誰にもアイデアはありますか?

ありがとう。

4

3 に答える 3

5

必要な動作は次のとおりです。

cto.ReadIntervalTimeout = 10;
cto.ReadTotalTimeoutConstant = 0;
cto.ReadTotalTimeoutMultiplier = 0;

最初のバイトに対して任意の長さでブロックし (ドキュメントに従って、後者の 2 つのフィールドをゼロに設定することで合計タイムアウトを無効にします)、データがストリーミングされている限り、バッファ サイズまで読み取ります。データに 10 ミリ秒のギャップがある場合、これまでに受け取ったもので返されます。

于 2014-09-24T01:25:43.683 に答える
1

CPU を 100% (またはそれに近い) 使用している場合は、別の場所で何か間違ったことをしているように聞こえます。以前の回答で示したように、何年もの間、タイムアウトをすべて 1 に設定してコードを使用してきました。後で。それは十分に機能しているので、まったく調整することはありませんでした。ほんの一例として、GPS からの入力を読み取ります (シリアル ポートの使用を模倣している唯一のものです)。 GPS を見ると、まだ 0:00:00 秒の CPU 使用時間が表示されています (実行中かどうかにかかわらず、CPU 使用率に違いは見られません)。

GPS が最速のシリアル デバイスではない (それに近い) ことは確かに認めますが、それでも ~100% 対 ~0% の話です。それは明らかにかなり深刻な違いです。

于 2012-04-30T22:14:17.160 に答える
0
if (dwEvtMask == EV_RXCHAR )
{
   Sleep(1);
   if (dwLength > 2)
    {
      Sleep(1);
      Readfile( m_Serial->m_hCom, data,dwLength, &dwBytesRead, &Overlapped);
      pDlg->PostMessage(WM_RECEIVE,0,0);
    }
}
于 2012-12-06T04:51:32.773 に答える