はじめに
Visual C++でミューテックスを使った排他制御のサンプルプログラムを作ってみました。
アプリケーションの二重起動を防止するのによく使われるやつです。
以下の記事が参考になりました。
ミューテックスを獲得するプログラム
以下のソースコードは、ミューテックスが他のプロセスで獲得されていないことを確認した後、ミューテックスを獲得します。
何かキーを押されたら、ミューテックスを即座に解放します。
// CreateMutex.cpp : コンソール アプリケーションのエントリ ポイントを定義します。 // #include "stdafx.h" #include <windows.h> #include <locale.h> #include <conio.h> int _tmain(int argc, _TCHAR* argv[]) { _tsetlocale( LC_ALL, _T("Japanese") ); wchar_t* MUTEX_KEY = L"Global\\MUTEX_KEY"; // キー名 // ミューテックが獲得されているかを調べる HANDLE hMutex = ::OpenMutex(MUTEX_ALL_ACCESS, FALSE, MUTEX_KEY); if(hMutex != NULL) { _tprintf(_T("すでに別のプロセスで獲得されています。\n")); } else { // ミューテックスを獲得する hMutex = CreateMutex(NULL, FALSE, MUTEX_KEY); if(::GetLastError() == ERROR_ALREADY_EXISTS) { _tprintf(_T("すでに別のプロセスで獲得されています。\n")); } else { _tprintf(_T("ミューテックスを獲得しました。\n")); } } _getch(); // キー入力を待つ if(hMutex != NULL) { // ミューテックスを解放する ::CloseHandle(hMutex); } return 0; }
ミューテックスが誰かに獲得されているかを調べるプログラム
以下のソースコードは、ミューテックスが他のプロセスで獲得されていないかどうかを調べます。
// CheckMutex.cpp : コンソール アプリケーションのエントリ ポイントを定義します。 // #include "stdafx.h" #include <windows.h> #include <locale.h> #include <conio.h> int _tmain(int argc, _TCHAR* argv[]) { _tsetlocale( LC_ALL, _T("Japanese") ); wchar_t* MUTEX_KEY = L"Global\\MUTEX_KEY"; // キー名 // ミューテックが獲得されているかを調べる HANDLE hMutex = ::OpenMutex(MUTEX_ALL_ACCESS, FALSE, MUTEX_KEY); if(hMutex != NULL) { _tprintf(_T("すでに別のプロセスで獲得されています。\n")); } else { _tprintf(_T("ミューテックスは誰にも獲得されていません。\n")); } _getch(); // キー入力を待つ if(hMutex != NULL) { // ロックはしていないけど、念のためミューテックスを解放する ::CloseHandle(hMutex); } return 0; }
グローバルミューテックス
サンプルプログラム内でミューテックスのキーに"Global"というプレフィックスをつけています。
これをつけるとグローバルミューテックスになり、複数のユーザー環境が同時実行される場合でもミューテックスが効くようになります。
ミューテックスの名前としてアプリケーション固有の名前を指定する。その際、その名前の先頭に「Global\」というプレフィックスを付加して「グローバル・ミューテックス」にすれば、Windows XPで実装された「Fast User Switching(参考:「新世代Windows、Windows XPを初体験(3)」)」のように複数のユーザー環境が同時実行される場合でも、複数ユーザー間でのアプリケーションの多重起動を禁止できる。
@IT:.NET TIPS Windowsアプリケーションの多重起動を禁止するには? - C# VB.NET Windowsフォーム