- - PR -
SharedMemoryの排他制御について
投稿者 | 投稿内容 | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2007-03-21 14:33
VC++7(VS-2003)にてSharedMemoryの機能を使っています。
SharedMemoryといっているのは OpenFileMapping() CreateFileMapping() MapViewOfFile() 等のAPIを使用してWindowsのページングファイル内にメモリ上の情報を読み書きする機能と認識しています。 このSharedMemoryはDLLで提供される予定です。 DLLは複数のexeから呼出され、読み書きされます。 当然、排他制御のような機能が必要となると考えています。 実際に排他制御を実現するにはどのような手法があるのでしょうか? 自分が今、考えているのはMutexを使って排他制御するやり方です。 SharedMemory-DLL内のAPIがコールされる度に、関数内でMutexを作成、チェックし、一度に一つのexeしか処理できないようにしたいと考えています。 このやり方は一般的でしょうか? 又、自分の中で SharedMemory-DLL内でMutextを使用するのではなく、SharedMemory-DLLを 呼出すほうのexe内でMutexを使って制御すべきなのか? と、言う軽い疑問もあったりします。 どなたか、経験の有る方等、アドバイスいただきたいです。 宜しくお願いします。 | ||||||||||||
|
投稿日時: 2007-03-21 17:44
Windowsでページングファイルというと、 Swapファイルと解釈してしまう気がします。 ファイルマッピングは、通常のファイルを仮想メモリにマッピングして、 メモリの読み書きでファイルを扱えるようにするためのものです。 その辺りの仕組みを応用して、実ファイルのないマッピングを 共有メモリとしても扱えるという方が正確なのではないでしょうか。
DLL内のAPIがコールされる度にMutexを生成したのでは、 異なるMutexとなるので排他制御の意味がないのでは? 複数プロセスから使う場合は、名前付き、もしくは、 親プロセスから継承させる方法のどちらかだったと思います。 「作成」が名前付きMutexの「Create/Open」の意味なら問題ありません。
設計にもよるとは思いますが、 共有メモリをDLLの外部に仕様として公開するのですか? 一般的にはプロセス間通信の詳細として隠蔽すると思います。 DLLの外部にはもっと高水準のAPIを提供するものですよね。 性能要件などの理由もあるので一概には言えませんが、 これらの制御をDLLの外部で行うべきではないと思います。 | ||||||||||||
|
投稿日時: 2007-03-21 17:47
こんにちは。
Mutexでよいと思います。
私ならこっちです。共有メモリの機能と排他制御の機能は別々に提供して欲しいです。 例えば、 1.共有メモリのデータを読み込み 2.データの一部を変更 3.共有メモリへデータを書き戻し を想定した場合、1〜3の一連の処理の間でロックを掛けたいので。
FileMapping(共有メモリ)とMutexの組み合わせは実際の開発で経験ありますね。 いちいち覚えていないのですが少なくとも2つ以上の開発で使いました。 | ||||||||||||
|
投稿日時: 2007-03-21 18:17
ファイルマッピングは、ユーザファイルだけではなく、オプションでページファイル上の領域を使用することも出来ますよ。
この表現は微妙ですね。 ファイルマッピングの主目的は(結果として行われる)ファイル更新ではなく、ページファイル、あるいはユーザファイルを足がかりとした比較的大規模のメモリ共有によるプロセス間通信の実現にあります。
「実ファイルがない(=ページファイルを利用したファイルマッピング)」のことを指しているのかもしれませんが、ファイルマッピングはその仕組み上実ファイルが必須です。 | ||||||||||||
|
投稿日時: 2007-03-21 18:57
単に順番として、 1. ファイルI/Oをメモリにマッピングする 2. 同一ファイルのマッピングを同一物理ページに割り当てる 3. その結果、プロセス間で共有メモリを扱うことが可能になる という方向の説明をしただけです。 が、確かに表現としてはよくないですね。
最終的にページファイルは利用される可能性は高いでしょう。 Unix系のmmapではAPIの仕様上、ファイルが必須となります。 ただ、Windowsでは、システムにページファイルなし、 かつ、マッピング先のファイルを指定しない状態でも、 マッピングの名前による共有も可能だったと思うのですが。 こちらの場合はSysV IPCの共有メモリのイメージに近いと思います。 | ||||||||||||
|
投稿日時: 2007-03-22 09:02
CreateFileMapping() のヘルプには、CreateFileMapping() に INVALID_HANDLE_VALUE を渡した時はページファイル上に領域確保が試みられる、と記載されています。 ページファイルを使わないようにOS設定を構成した場合にどう振舞うかは、記載がないので分かりません。 実メモリが十分にあれば、メモリだけでも動作するような気はしますね。 | ||||||||||||
|
投稿日時: 2007-03-22 11:45
皆様、アドバイスありがとうございます。
既に渋木さんから指摘あるように、Windowsのページファイルを使ったファイルマッピングを使用したいと考えていました。 今回は確実に仮想メモリ=0(なし)の環境ではないので、ページファイルを利用する事に問題はないかと思っていました。 ただ、今回作成するプログラム類が異常終了した時にページファイル上にゴミが残ってしまう点だけは危惧しておりますが・・・ (話を戻して・・)mutexを使った排他制御が一般的である(まぁ、普通)事を聞き、mutexを使用しての排他制御を実装したい。と、考えました。 その上で気になるのが、あしゅさんの・・・ >DLL内のAPIがコールされる度にMutexを生成したのでは、 >異なるMutexとなるので排他制御の意味がないのでは? > >複数プロセスから使う場合は、名前付き、もしくは、 >親プロセスから継承させる方法のどちらかだったと思います。 > >「作成」が名前付きMutexの「Create/Open」の意味なら問題ありません。 と、言うくだりです。 今の私の考えだと・・・ DLL内で writeSharedMemory() readSharedMemory() を定義し、各exeは上記APIを使用します。 各APIの中でmutexを生成、チェックするのですが、ここで言うmutextの生成とは Mutext(FALSE,"MyMutex") のように名前付きMutexの作成を意味しています。 チェックとは OpenExisting("MyMutex") を行う事を意味しています。 DLL内で唯一の名前を定義し(上記で言えば"MyMutex")、その名前を使ってMutexを作成、チェックすれば、複数のexe間でも、唯一のMutexしか使用しない。と、思っていたのですがこの認識は誤りでしょうか? 説明がふがいないのですが、宜しくアドバイスお願いします。 | ||||||||||||
|
投稿日時: 2007-03-22 12:46
Mutext(FALSE,"MyMutex") や OpenExisting("MyMutex") が何しているのか分かりませんが、チェックなどしなくても、名前付き Mutex を作る際にまだ Mumtex が存在しなければ作るし、既に存在すれば作成済みの Mutex のハンドルを返しますよね。
_________________ 囚人のジレンマな日々 |