2

バイナリ ファイルを処理する次のコードがあります。スレッドを使用し、バイナリ ファイルの各行を ThreadPool 内のスレッドに割り当てることで、処理負荷を分割したいと考えています。各行の処理時間はわずかですが、数百行を含む可能性のあるファイルを処理する場合、ワークロードを分割することは理にかなっています。

私の質問は BinaryReader とスレッド セーフに関するものです。まず第一に、私がやっていることは許容範囲内です。PROCESS_Binary_Return_lineData メソッドには、各行のバイナリのみを渡す方がよいと感じています。

以下のコードは概念的なものであることに注意してください。マルチスレッドに関する私の知識はまだ始まったばかりなので、これに関する少しのガイダンスを探しています。おそらく、同じ結果を達成するためのより良い方法、つまり各バイナリ行の分割処理があります。

        var dic = new Dictionary<DateTime, Data>();        
        var resetEvent = new ManualResetEvent(false);

        using (var b = new BinaryReader(File.Open(Constants.dataFile, 
                            FileMode.Open, FileAccess.Read, FileShare.Read)))
        {
        var lByte = b.BaseStream.Length;
        var toProcess = 0;

        while (lByte >= DATALENGTH)
        {
            b.BaseStream.Position = lByte;
            lByte = lByte - AB_DATALENGTH;

            ThreadPool.QueueUserWorkItem(delegate
            {
                Interlocked.Increment(ref toProcess);
                var lineData = PROCESS_Binary_Return_lineData(b);

                lock(dic)
                {
                    if (!dic.ContainsKey(lineData.DateTime))
                    {
                     dic.Add(lineData.DateTime, lineData); 
                    }
                }

                if (Interlocked.Decrement(ref toProcess) == 0) resetEvent.Set();
            }, null);
        }
        }

        resetEvent.WaitOne();
4

3 に答える 3

3

これは私にはスレッドセーフに見えません。複数の作業項目がキューに入れられていて、そのうちの 2 つが同時に実行された場合、割り当てと読み取りの間でリーダーの位置が簡単に変わる可能性があります。

これにどうしてもスレッドを使用する場合は、メイン スレッドでデータを読み取り、結果のバイト配列を読み取り用にキューに入れることをお勧めします。ファイルから読み取る各スレッドを含むソリューションにはロックが含まれます。その時点では、スレッドを使用しても何も得られません。

于 2010-04-21T10:09:49.663 に答える
2

ファイル処理のパフォーマンスを向上させるためにスレッドを使用する意味はほとんどありません。スレッドをマルチコア CPU で実行すると、より多くの CPU サイクルが提供されます。これは、ファイルを処理するときに不足するリソースになることはめったにありません。さらにディスクが必要です。もちろん、オプションではありません。

これを最初にスモークテストします。ファイルがファイル システム キャッシュに保存されないように、マシンを再起動します。シングルスレッド プログラムを実行し、CPU 負荷を観察します。Taskmgr.exe、[パフォーマンス] タブはそのために適しています。100% の負荷で 1 つの CPU が限界に達していない場合、別の CPU を追加してもプログラムを高速化することはできません。

于 2010-04-21T12:57:22.453 に答える
0

「各行のバイナリのみを PROCESS_Binary_Return_lineData メソッドに渡す方がよいと感じています。」

はい、それを行う必要があります。デリゲートは、再配置される前に BinaryReader からの読み取りに取り掛からない可能性があるためです。

于 2010-04-21T10:09:32.640 に答える