読者です 読者をやめる 読者になる 読者になる

小さい頃はエラ呼吸

いつのまにやら肺で呼吸をしています。


VC++で作るミューテックス(mutex)を使った排他制御

Visual Studio
はじめに

Visual C++でミューテックスを使った排他制御のサンプルプログラムを作ってみました。
アプリケーションの二重起動を防止するのによく使われるやつです。

以下の記事が参考になりました。

ミューテックスによる2重起動防止の罠 - Dive to the Softwareミューテックスによる2重起動防止の罠 - Dive to the Software

ミューテックスを獲得するプログラム

以下のソースコードは、ミューテックスが他のプロセスで獲得されていないことを確認した後、ミューテックスを獲得します。
何かキーを押されたら、ミューテックスを即座に解放します。

// 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フォーム はてなブックマーク - @IT:.NET TIPS Windowsアプリケーションの多重起動を禁止するには? - C# VB.NET Windowsフォーム