4

プロセス間の通信が共有メモリを使用して行われるプロジェクトを見たことがあります (たとえば::CreateFileMapping、Windows で使用)。プロセスの 1 つが共有メモリでデータが利用可能であることを通知するたびに、名前付きイベントを使用した同期メカニズムが関係者に通知されます。共有メモリの内容が変更されたこと。

新しい情報を読み取るプロセスが、データのコピーを無効にし、プロデューサー プロセスによって「公開」されたらメイン メモリから読み取る必要があることを知るために、適切なメモリ フェンスが存在しないという事実が懸念されます。 .

Windows で共有メモリを使用してこれを行う方法を知っていますか?

EDIT ファイルマッピングを作成した後、プロセスはMapViewOfFile() APIを1回だけ使用し、共有データへの新しい変更はすべて、MapViewOfFile()への最初の呼び出しによって取得されたポインターを使用して、共有メモリを介して送信された新しいデータを読み取ることを追加したかっただけです. 正しい同期では、共有メモリ内のデータが変更されるたびに、データを読み取るプロセスで毎回 MapViewOfFile() を作成する必要がありますか?

4

3 に答える 3

5

変更の通知に Windows 名前付きイベントを使用する場合は、すべて問題ありません。

プロセス A はデータを変更し、 を呼び出しますSetEvent

プロセス B は、WaitForSingleObjectまたは類似のイベントを使用して待機し、設定されていることを確認します。

次に、プロセス B がデータを読み取ります。への呼び出しの前にプロセス A によって行われた変更がプロセス B によって読み取られるWaitForSingleObjectようにするために必要なすべての同期が含まれています。SetEvent

もちろん、 を呼び出したSetEventにデータに変更を加えた場合、プロセス B がデータを読み取るときに、これらが表示される場合と表示されない場合があります。

イベントを使用したくない場合は、 で作成された Mutex を使用するか、やなどの関数CreateMutexを使用してロックフリー コードを記述できます。Interlocked...InterlockedExchangeInterlockedIncrement

どのように同期を行っても、MapViewOfFile複数回呼び出す必要はありません。

于 2012-04-17T16:37:22.837 に答える
4

Windowsで共有メモリを探しているのは、InterlockedExchange関数です。こちらのmsdnの記事を参照してください。本当に重要な部分が引用されています:

この関数は、完全なメモリバリア(またはフェンス)を生成して、メモリ操作が順番に完了するようにします。

これはクロスプロセスで機能します。私は以前にそれを使ったことがあり、共有メモリの上にミューテックスのような構造を実装するのに100%信頼できることがわかりました。

それを行う方法は、「設定された」値と交換することです。あなたが「クリア」に戻った場合、あなたはそれを持っています(それはクリアでした)が、あなたが「セット」に戻った場合、他の誰かがそれを持っていました。あなたはそれを「得る」まで、ループしたり、ループの合間に寝たりします。基本的にこれ:

#define LOCK_SET 1
#define LOCK_CLEAR 0

int* lock_location = LOCK_LOCATION; // ensure this is in shared memory
if (InterlockedExchange(lock_location, LOCK_SET) == LOCK_CLEAR)
{
    return true; // got the lock
}
else
{
    return false; // didn't get the lock
}

上記のように、「取得」するまでループします。

于 2012-04-16T15:42:21.400 に答える
0

プロセス A をデータ プロデューサー、プロセス B をデータ コンシューマーと呼びましょう。これまでは、プロセス A がプロセス B に新しいデータが生成されたことを通知するメカニズムがありました。データが消費されたことをプロセス A に伝える逆方向の通知 (B から A へ) を作成することをお勧めします。パフォーマンス上の理由から、データが消費されるまでプロセス A を待機させたくない場合は、共有メモリにリング バッファを設定できます。

于 2012-04-16T14:40:31.947 に答える