1

したがって、ファイルを開き、内容を行ごとに読み取り、各行を別の場所の関数に使用し、終了したらファイルを巻き戻す次のコードがあるとします。

FILE *file = Open_File();
char line[max];
while (!EndofFile()) 
{
    int length = GetLength(line);
    if (length > 0) 
    {
       DoStuffToLine(line)
    }
}
rewind(file);

ここでスレッドを使用して同時実行性を追加する方法があるかどうか疑問に思っています。ファイルに書き込むのではなく、読み取るだけなので、競合状態について心配する必要はないように感じます。ただし、while ループ内のコードを処理する方法がわかりません。1 つのスレッドがファイルをループし、別のスレッドが同時にファイルをループしている場合、互いに行をスキップし、他のスレッドを作成するからです。エラーなど?これにアプローチする良い方法は何ですか?

4

3 に答える 3

2

読み取りパフォーマンスを向上させるためにこれを行おうとしている場合、これはほぼ確実にディスクI / Oバウンドになるため、失望する可能性があります。スレッドを追加しても、OSとディスクコントローラーがデータをより速くフェッチするのに役立ちません。

ただし、データを並列処理するだけの場合は、別の問題になります。その場合、ファイル全体をどこかのメモリバッファに読み込んでから、スレッドに並行して処理させます。そうすれば、ファイルポインタを巻き戻すことによるスレッドの安全性や、その他の厄介な問題について心配する必要がありません。

もちろん、実行している内容によっては、マルチスレッド部分に他のロックメカニズムを使用する必要がある可能性がありますが、ファイルへのアクセスを開始するときに標準ライブラリが何を実行するかについて心配する必要はありません。複数のスレッドで。

于 2012-11-15T22:06:55.193 に答える
1

並行性により、競合状態の問題がいくつか追加されます。

1. EndofFile()関数はループの開始時に評価されます。この関数が2つのスレッドに対してtrueを返し、一方のスレッドがファイルの終わりに到達し、もう一方のスレッドがファイルを読み取ろうとすることが常に発生する可能性があります。スレッドが実行されている可能性がある場合。
2. GetLength関数についても同じことが言えます。スレッドに長さ情報がある場合、別のスレッドが別の行を読み取る可能性があるため、長さが変わる可能性があります。
3.ファイルを順番に読み取っていますが、ファイルを巻き戻しても、IOポインタの現在の位置が他のスレッドによって変更されることが常に発生する可能性があります。

さらに、Telginが指摘したように、ファイルの読み取りはCPUにバインドされていませんが、I / Oにバインドされているため、ファイルを読み取るシステムも同様です。いくつかのロックが必要なため、パフォーマンスを向上させることはできません。オーバーヘッドが発生します。

于 2012-11-15T22:12:57.767 に答える
0

これが最善のアプローチかどうかはわかりません。ただし、ファイルを読み取ることはできます。次に、それを2つの別々のオブジェクトに格納し、ファイルの代わりにオブジェクトを読み取ります。後で必ずクリーンアップを行ってください。

于 2012-11-15T22:08:08.763 に答える