CreateMutex ミューテックスオブジェクトの作成

Cの宣言:

HANDLE CreateMutex(LPSECURITY_ATTRIBUTES pSAttr, BOOL fOwner, LPCTSTR sMutexName);

VBの宣言:

'セキュリティ記述子をLongのアドレス値で渡す場合
Declare Function CreateMutex Lib "kernel32" Alias "CreateMutexA" ( _
	ByVal pSAttr As Long, _
	ByVal fOwner As Long, _
	ByVal sMutexName As String) As Long

'セキュリティ記述子を参照で渡す場合
Declare Function CreateMutex Lib "kernel32" Alias "CreateMutexA" ( _
	ByRef SAttr As SECURITY_ATTRIBUTES, _
	ByVal fOwner As Long, _
	ByVal sMutexName As String) As Long

説明:

ミューテックスオブジェクトを作成する。sMutexNameで指定したミューテックスオブジェクトが既に存在する場合、このミューテックスオブジェクトをオープンし、そのハンドルを返す。

関数の実行が成功すると、ミューテックスオブジェクトのハンドルが返される。新規ミューテックスオブジェクトが作成された場合は、GetLastError()の戻り値は0となり、既存のミューテックスオブジェクトがオープンされた場合は、GetLastError()の戻り値はERROR_ALREADY_EXISTINGとなる。

名前のないミューテックスオブジェクトを作成することも可能である。この場合、そのミューテックスオブジェクトへの参照は、ハンドルによってのみ可能となる。名前のないミューテックスオブジェクトは複数作成可能であり、ハンドルによって識別される。

取得したハンドルは、CloseHandleによって開放する。オープンされているハンドルが全てクローズされると、システムは自動的にミューテックスオブジェクトを削除する。

ミューテックスオブジェクトをオープンしているプロセスがクローズせずに終了した場合、システムは自動的にプロセスがオープンしていたハンドルをクローズする。しかし、スレッドがミューテックスオブジェクトのハンドルをクローズせずに終了した場合、所有権が開放されるのみで、クローズされないままの状態となる。この場合、待機関数はWAIT_ABNDONEDを返す。

fOwnerによって、作成と同時に呼び出し元スレッドが所有権を取得するか否かを指定することができる。

引数の意味は、以下の通り。
pSAttr (IN) ミューテックスオブジェクトに与えるセキュリティ属性
fOwner (IN) 作成と同時に所有権を取得するか否かを表す真偽値
sMutexName (IN) ミューテックスオブジェクトの名前。長さの最大はMAX_PATH。名前は、“\”を含んではならない。名前は、大文字・小文字が区別される。

戻り値は、作成またはオープンしたミューテックスオブジェクトのハンドルである。ミューテックスオブジェクトの作成に失敗した場合、NULLが返される。

fOwner == TRUE の例(C言語):

/* 既にアプリケーションが起動しているかどうかチェックする
 * 呼び出し元では、WinMainの初めにこの関数を1度だけ呼び出すようにする
 * 戻り値:TRUE...すでにアプリケーションが起動しているかどうかを表す真偽値
 */
BOOL CheckAppInstance()
{
	HANDLE hMutex;
	DWORD error_no;
	BOOL bAppInstance = FALSE;
	
	hMutex = CreateMutex(NULL, TRUE, "Mutex object for sample code"); /* ミューテックスの作成 */

	error_no = GetLastError(); /* エラー番号の取得 */
	
	/* 判定 */
	if(error_no == 0)
		bAppInstance = FALSE;
	else if(error_no == ERROR_ALREADY_EXISTS)
		bAppInstance = TRUE;
	
	return(bAppInstance);
}

fOwner == FALSE の例(C言語):

#include <windows.h>
#include <stdio.h>

#define MUTEX_NAME "Mutex Object of Sample 2"

/* スレッド用関数
 * “処理”の部分が、排他的な処理となる
 * ThreadCount: 何番目のスレッドか
 */
DWORD WINAPI DoThread(DWORD ThreadCount)
{
	HANDLE hMutex;
	int i;

	hMutex = OpenMutex(MUTEX_ALL_ACCESS, FALSE, MUTEX_NAME);

	for(i=0; i<3; i++) {
		/* 所有権獲得まで待機 */
		WaitForSingleObject(hMutex, INFINITE);

		/* 処理 */
		printf("スレッド%d: 処理開始\n", ThreadCount);
		Sleep(3000);
		printf("スレッド%d: 処理終了\n", ThreadCount);

		/* 開放 */
		ReleaseMutex(hMutex);
	}
	
	CloseHandle(hMutex);
	return(0);
}

/* メイン関数
 * 排他処理に用いるミューテックスを作成
 * スレッドを作成
 * スレッドの終了を待機
 */
int main(int argc, char **argv)
{
	HANDLE hThread[2];
	DWORD ThreadID[2];
	HANDLE hMutex;
	int i;

	/* ミューテックスオブジェクトの作成 */
	hMutex = CreateMutex(NULL, FALSE, MUTEX_NAME);

	/* スレッドを2つ作成 */
	for(i=0; i<2; i++) {
		hThread[i] = CreateThread(
			NULL, 0, (LPTHREAD_START_ROUTINE)DoThread,
			(LPVOID)i, 0, &ThreadID[i]);
		Sleep(1000);
	}

	/* スレッドの終了まで待機 */
	WaitForMultipleObjects(2, hThread, TRUE, INFINITE);

	/* 後処理 */
	CloseHandle(hMutex);
	CloseHandle(hThread[0]);
	CloseHandle(hThread[1]);

	return(0);
}

(original text:1998/12/25 更新)

本ドキュメントの内容は保証しません。本ドキュメントによって生じた結果について、一切の責任を負いません。