1

プロセスの標準出力 (バイナリ データ) を文字列バッファーに入れ、それを別のスレッドで使用する必要があります。

プロデューサーは次のとおりです。

while (ReadFile(ffmpeg_OUT_Rd, cbBuffer, sizeof(cbBuffer), &byteRead, NULL)){
    tByte += byteRead;   //total bytes
    sb->sputn(cbBuffer, byteRead);
}
m_bIsFinished = true;
printf("%d bytes are generated.\n", tByte);

消費者は次のとおりです。

while (!PCS_DISPATCHER_INSTANCE->IsFinished())
    Sleep(200);
Sleep(5000);
Mystringbuf* sb = PCS_DISPATCHER_INSTANCE->sb;
printf("Avail: %d\n", sb->in_avail());

コンシューマーは、プロデューサーによって生成されたのすべてのバイトを取得できないことが判明しました。( tByte <> sb->in_avail())

内部バッファリングの問題の一種ですか?はいの場合、stringbuf に内部バッファを強制的にフラッシュさせる方法は?

4

1 に答える 1

3

Astreambufにはフラッシュのようなものはありません。書き込みはバッファに直接行われます。pubsync()filebuf などの派生オブジェクトを使用する場合に役立つメンバーがあります。しかし、これはあなたのケースには当てはまりません。

あなたの問題は確かにまたはでのデータ競合に起因しています。ミューテックスまたは. がアトミックでない場合、および の実装によっては、スレッド間の同期が保証されない場合があります (たとえば、プロデューサーはメモリに書き込むことができますが、コンシューマーは CPU メモリ キャッシュから古い値を引き続き取得します)。そんなデータ競争。 sputn()is_avail()atomicm_bIsFinishedisFinished()

編集:

単一のスレッド内で問題が発生し、潜在的な競合状態が解消される場合は、streambuf. これは、シングル スレッド アプリケーションで MSVC13 を使用して体験できました。

  • トレースは、読み取られたバイト数が正確であることを示しましたが、in_avail()結果はループ全体を通して常に tByte 以下でした。
  • streambuf を読み取るときに、正しい合計バイト数が読み取られました (したがって、in_avail() で示されるよりも多く)。

この動作は準拠しています。C++ 標準によると、読み取り位置が使用可能な場合はin_avail()egptr() - gptr() を返し、それ以外の場合はshowmanyc() を返します。 後者は、シーケンスで使用可能な文字数の推定値を返すものとして定義されています。in_avail()与えられた唯一の保証は、 eof に遭遇することなく 、少なくともバイトを読み取ることができるということです。

回避策として、使用sb->pubseekoff(0,ios::end)- sb->pubseekoff(0,ios::beg);可能なバイト数をカウントし、streambuf を読み取る前に sb->pubseekoff(0,ios::beg) に再配置されていることを確認してください。

于 2014-09-14T12:48:21.740 に答える