2011-01-02 13 views
3

可能性の重複:で、複数のクライアントアプリケーションにロードされているMS VS C++急行、中にDLLファイルを足す
DLL thread safetyDLLミューテックス - 例

こんにちは

イム同時に、ロードされたDLLの他のインスタンスと共有メモリを使用します。私たちは、DLLは、次のようになりますと仮定しましょう:2つの以上のクライアントから同時に呼び出された

#include stdafx.h 
#pragma data_seg (".TEST") 
//Shared variables 
#pragma data_seg() 
#pragma comment(linker, "/section:.TEST,RWS") 
_DLLAPI void __stdcall doCalc() 
{ 
//Do critical stuff 
} 

doCalc場合、システムがクラッシュします。 関数がすでに呼び出されている場合、他の呼び出しを「停止」するミューテックスを作成するにはどうすればよいですか? インターネットでまともなものを探すために過去2時間を費やしたので、例を挙げてください)

ありがとうございます。

答えて

4

すべてのプロセスのコード:

// At the start of every process 
HANDLE sharedMemoryMutex = CreateMutex(NULL, FALSE, "My shared memory mutex"); 

// When you want to access shared memory: 
DWORD dwWaitResult = WaitForSingleObject(sharedMemoryMutex, INFINITE); 

if (dwWaitResult == WAIT_OBJECT_0 || dwWaitResult == WAIT_ABANDONED) 
{ 
    if (dwWaitResult == WAIT_ABANDONED) 
    { 
     // Shared memory is maybe in inconsistent state because other program 
     // crashed while holding the mutex. Check the memory for consistency 
     ... 
    } 

    // Access your shared memory 
    ... 

    // After this line other processes can access shared memory 
    ReleaseMutex(sharedMemoryMutex); 
} 
+0

1)他のプロセス(他のユーザーのコンテキストで実行中)が同じmutexを取得し、2)他のプロセスもmutexにアクセスできることを確認する必要があります。これを行うには、1)ミューテックス名に "Global \"接頭辞を使用し、2)ミューテックスを作成するときに適切なセキュリティ記述子を指定します。 – villintehaspam

+0

@villintehaspam、あなたのアサーションは有効ですが、OPのケースではそれらが適用されるのではないかと疑います。 – Dialecticus

+0

あなたはおそらく正しいでしょう - 私はこの情報が存在していなければならないと考えています。 – villintehaspam

0

MSDN hereにある「Using Mutex Objects」サンプルから開始できます。プロセス間でミューテックスを共有するには、CreateMutexコールを変更して名前を付ける必要があります。

+0

1)他のプロセス(他のユーザーのコンテキストで実行中)が同じmutexを取得し、2)他のプロセスがmutexにもアクセスできることを確認する必要があります。これを行うには、1)ミューテックス名に "Global \"接頭辞を使用し、2)ミューテックスを作成するときに適切なセキュリティ記述子を指定します。 – villintehaspam

+0

彼は、異なるユーザーとして実行されているプロセス間でマッピングされた書き込み可能なメモリを共有している場合、彼は巨大なセキュリティホールを持っています。グローバル名前空間のミューテックスに依存することは、別の巨大なセキュリティホールです。なぜなら、それは簡単に逃げることができるからです。 – Michael

+0

右:ミューテックスとファイルマッピングの両方に同じ名前のスコープを使用する必要があります。おそらく両方ともセッションローカルである必要があります。 –

0

おそらく共有としてセクションをマークするために、リンカを使用していない、共有メモリを作成するために、共有ファイルマッピングオブジェクトを使用する必要があります。これを管理する比較的簡単な方法は、すべての共有変数を単一のstructに入れ、MapViewOfFileの戻り値をこの構造体へのポインタにキャストすることです。

もちろん、この共有領域にはポインタを置くことはできませんが、プロセス間でインデックス情報(もちろん共有領域の配列を参照)を交換できます。

リンカ共有セクションであっても、すべてのプロセスで同じアドレスにロードされることは保証されません。

関連する問題