2013-05-03 43 views
11

メモリマップファイルの名前が示すように、高速データ処理のために、C#でクラスMemoryMappedFileを使用して大きなファイルの一部をメモリにマップできることを理解します。私がメモリマッピングされたファイルで何をしたいのかは、マップされたメモリを並列処理することです。そのために、私が質問メモリマップファイルのデータを並列処理する方法

を以下している
  1. MemoryMappedFileViewAccessorスレッドセーフとParallel.For-安全ですか?私は実際に質問をテストするためのデモプログラムを作った、それは働いているようだ。しかし、これについての参照を見つけることができません。答えが「はい」の場合、私は完了です。それ以外の場合は、
  2. アレイにマップされたメモリに直接アクセスする方法はありますか?私はMemoryMappedFileViewAccessorがReadArrayメソッドを持っていることを知っていますが、このメソッドを使うのはメモリの複製です。
+0

あなたの並列処理では、ファイルを変更するか、またはファイルの読み取りのみを行いますか? –

+0

@CharlesLambertいいえ、データ処理は、基本的にマップされたメモリにアクセスしているaccessor.Writeまたはaccessor.Readの操作を伴います。メモリマップされたファイルは実際にファイル操作を処理します。 –

答えて

9

これを推測することができます。メモリマップされたファイルは、複数のプロセスがバイトにアクセスできるプログラム内の単なるメモリチャンクです。このチャンクは特定のアドレスに存在するため、管理されたコードではかなり厄介です。これは、ポインタを使用してデータにアクセスする必要があり、管理されたコードではタブーになっています。 MemoryMappedFileViewAccessorはそのポインタをラップします。は、データを管理対象メモリから共有メモリにコピーします。これは、MMFを使用する主な理由と、.NETでの表示に時間がかかりすぎた理由を打ち消すことに注意してください。代わりに名前付きパイプを使用しないようにしてください。

これを推論すると、MMFはグローバル変数がコード内にあるように、共有メモリであるため、設計上スレッドセーフではありません。スレッドが共有メモリの同じセクションを読み書きする場合は、同じことが起こります。そして、あなたは同じことにも同じように保護する必要があります。一つのスレッドだけが共有セクションにアクセスできるようにするロックです。

また、MMFを読み書きするプロセス間でそのロックを実装する必要があることにも注意してください。どちらが苦痛になるかは、「マスタ」プロセスが作成し、「スレーブ」プロセスが開く名前付きミューテックスを使用する必要があります。あなたはそのロックの必要条件を詮索することはできません。注目すべきは、あなたの質問でこれを世話したことは一度も言及していないことです。

1つのプロセス内で、MMFの同じセクションにアクセスしないスレッドは、互いの方法で取得できません。異なる変数にアクセスする2つのスレッドのように、同期は必要ありません。他のプロセスがセクションに書き込むことができないことを保証するミューテックスを保持している限り。これはおそらく、セマフォを使用してMMFアクセスを保護したいということを意味します。ミューテックスは1つのスレッドでしか取得できません。

3

読み取り専用フィールドを持っていませんが、内部的には、MemoryMappedViewAccessorは、不変現れUnmanagedMemoryAccessorから誘導され、 - 少なくともそれは、読み取り/書き込み操作中に既存のフィールドを変更しません、それはスレッドセーフになりました。ターンでは、それはcomments headerに次のテキストが含まれていSafeBufferクラスからメモリマップドファイルのデータを読み取ります

/* Keep the penalties for using this class small, both in terms of space 
// and time. Having multiple threads reading from a memory mapped file 
// will already require 2 additional interlocked operations. If we add in 
// a "current position" concept, that requires additional space in memory and 
// synchronization. Since the position in memory is often (but not always) 
// something that can be stored on the stack, we can save some memory by 
// excluding it from this object. However, avoiding the need for 
// synchronization is a more significant win. This design allows multiple 
// threads to read and write memory simultaneously without locks (as long as 
// you don't write to a region of memory that overlaps with what another 
// thread is accessing). 

だから私の推測では、メモリとの演算は、ありませんがあることが不思議ですが、ファイルは、スレッドセーフであるマッピングされたということですMSDNでこれを確認します。 MemoryMappedFileMemoryMappedViewAccessorの両方のための

0

1)MSDNのように述べている:

すべてのパブリックstatic(Visual BasicではShared)この型のメンバは、スレッドセーフです。どのインスタンスメンバーもスレッドセーフであるとは限りません。

2)MemoryMappedFileのポイントはメモリ割り当てを減らすものではありません。ディスクからファイルを読み込んでいた場合は、ファイルから読み込んだ項目を格納するためにメモリを割り当てる必要があります。これは、メモリマップされたファイルの場合も同様です。

+0

@Thomasメモリマップされたファイルは、もちろんアドレススペースを消費します。実際、名前のないメモリマップファイルは、同じ粒度の低レベルのOSメモリ割り当てとあまり変わりません。 – Neil

関連する問題