2

Qtを介してアプリケーションを開発しています。

このアプリケーションでは、メインスレッドはWebサーバーです。別のスレッドが大きなファイル(250mb)からデータを読み取り、それらを出力ファイル(〜2gb)に書き込むことがあります。

このスレッドはファイルに対して高いI/O操作を実行し、CPU iowaitは約70%です。

私の問題は、ファイルに書き込むときに、Webサーバーが迅速に応答しないことです。私が理解したのは、サーバーのqtソケット(Linuxの場合)は、ポーリングまたは選択イベントシステムに接続されたシステムソケットによって表されるということです。したがって、Qtは、ポーリングがイベントを発行したときにのみ、アプリケーションにシグナルを送信します。

私が思うに、ファイル書き込みを伴う巨大なio操作は、ポーリングシステムをブロックする可能性があるため、qtサーバーはソケットイベントを受信しません。スレッドがデータの書き込みを終了すると、すべてが正常になります。

ファイルの書き込みは次のようになります。

while(dataToRead){
    // context has the list of files to read and current step
    dataToRead = extractData(context, &pBuffer, &sizeBuf);

    fwrite (pBuffer, 1, sizeBuf, pOutFile);

    free(pBuffer);
    pBuffer = NULL;

    // usleep(100000);
}

usleep関数で休憩を追加すると、問題を回避するのに役立ちますが、十分な睡眠を使用しない場合は完全には役立ちません。しかし、スリープが長すぎるとパフォーマンスが低下し、私は可能な限り高速に生成されたファイルでした。

私が間違っているのは何ですか?できるだけ速くファイルの読み取り/書き込みを行うのは安全ですか?上記の機能でスリープは必須ですか?しかし、どうすれば良いタイムスライスを知ることができますか?

私はMintLMDE、Linux 3.2.0 64ビット、Intel Corei52500および標準HDDドライブに取り組んでいます。

編集:問題を再現するサンプルプログラムは、https ://bugreports.qt-project.org/secure/attachment/30436/TestQtBlocked.zipから入手できます。コンパイルするにはqtのqmakeが必要です。これを実行すると、空の3GBファイルが作成され、起動時にワーカースレッドが起動され、数秒でファイルが作成されます。この間にhttp:// localhost:8081 /に接続しようとし、F5を何度も実行してページを更新すると、応答が速くない場合があります。誰かが私のサンプルプログラムで私の問題を再現できれば役立つかもしれません、そして私に知らせてください。

4

2 に答える 2

1

メイン スレッドの選択呼び出しが不足している場合は、別のスレッドを作成してファイル I/O を実行します。イベントが Qt から来ると、ワーカー スレッドを起動して大きなファイル I/O を実行し、イベント ハンドラーからすぐに戻る何らかの IPC をトリガーします。

(これは、ファイルへの非同期書き込みがプログラム ロジックにとって意味があることを前提としています。それが正しいかどうかを判断できるのは、あなただけです。)

于 2012-12-12T19:55:51.740 に答える
0

man ページから: size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);

sizeBuf 、1要素を書きたい。

setvbuf でバッファリングを調整したい場合があります。

setvbuf(pOutfile, NULL, _IONBF, 0) - バッファリングを無効にします。

完全な例: http://publib.boulder.ibm.com/infocenter/iseries/v7r1m0/index.jsp?topic=%2Frtref%2Fsetvbuf.htm

ファイル ストリームではなく、ファイル記述子を操作するように切り替えたほうがよいでしょう。

ファイル記述子を使用すると、sendfile と slice を使用できます。男 sendfile 男スライス

于 2012-12-12T18:46:54.457 に答える