CreateMutex(A)

ミューテックスオブジェクトを作成またはオープンします。

オブジェクトに対するアクセスマスクを指定するにはCreateMutexEx関数を使用します。

HANDLE CreateMutexA(
    PSECURITY_ATTRIBUTES  psa,    // セキュリティ指定子.
    BOOL    bInitialOwner,        // 所有権指定フラグ.
    PCTSTR  pszMutexName          // オブジェクトの名前.
);

KERNEL32.DLL

引数

psa

オブジェクトの保護属性を設定するSECURITY_ATTRIBUTES構造体へのポインタを指定します。このパラメータに0 (NULL) を指定すると、ハンドルを子プロセスに継承しません。

SECURITY_ATTRIBUTES構造体のlpSecurityDescriptorメンバで、新しいミューテックスに対するセキュリティ記述子を設定します。lpSecurityDescriptorメンバに0 (NULL) を指定するとデフォルトのセキュリティ記述子が使用されます。ミューテックスに対するデフォルトのセキュリティ記述子でのACL(アクセス制御リスト)は、作成したプロセスのプライマリトークンまたは偽装アクセストークンに由来します。

Windows 95/98/Me: SECURITY_ATTRIBUTES構造体のlpSecurityDescriptorメンバは無視されます。

bInitialOwner

1 (TRUE) を指定し、かつ、呼び出しスレッドによって新しいミューテックスが作成された場合は、呼び出しスレッドは初期状態のミューテックスオブジェクトの所有権を取得します。それ以外の場合は、呼び出しスレッドはミューテックスの所有権を取得しません。

pszMutexName

ミューテックスオブジェクトを識別する名前を指定します。最大文字列サイズは260 (MAX_PATH) です。名前にはバックスラッシュ(\)以外の任意の文字が使用できます。名前の比較では大文字・小文字が区別されます。

指定した名前のミューテックスオブジェクトがすでに作成されている場合には、既存のオブジェクトに対してMUTEX_ALL_ACCESSアクセスを要求します。この場合、オブジェクトの所有権はすでに作成プロセスによって設定されているため、bInitialOwnerパラメータは無視されます。また、psaパラメータが0 (NULL) 以外の場合、ハンドルが継承可能かどうかを指定することはできますが、セキュリティ記述子は無視されます。

0 (NULL) を指定すると、名前なしのオブジェクトが作成されます。

指定した名前が既存のミューテックス以外の名前付きのカーネルオブジェクト(イベント、セマフォ、ウェイタブルタイマー、ジョブ、またはファイルマッピングオブジェクト)の名前と一致すると、関数は失敗し、GetLastError関数は6 ERROR_INVALID_HANDLEを返します。これは、これらのカーネルオブジェクトが同じ名前空間を共有しているために起こります。

オブジェクトの名前に "Global\" または "Local\" プレフィックスをつけることによって、それぞれ明示的にグローバル名前空間またはセッション名前空間にミューテックスオブジェクトを作成することができます。プレフィックス以降の部分には、バックスラッシュ文字「\」以外のすべての文字を使用することができます。高速なユーザーの切り替えはターミナルサービスセッションを使用して実装されています。アプリケーションが複数ユーザーをサポートするためには、カーネルオブジェクトの名前は、ターミナルサービスについて概説されたガイドラインに従う必要があります。

Windows 2000: ターミナルサービスが実行されていない場合は、 "Global\" および "Local\" プレフィックスは無視されます。プレフィックス以降の部分には、バックスラッシュ文字「\」以外のすべての文字を使用することができます。

Windows NT 4.0 以前: バックスラッシュ文字「\」以外のすべての文字を使用することができます。

Windows 95/98/Me: バックスラッシュ文字「\」以外のすべての文字を使用することができます。空文字列 "" も、オブジェクトの名前として有効です。

戻り値

成功すると、新たに作成されたミューテックスオブジェクトのハンドルが返ります。

失敗すると0 (NULL) が返ります。拡張エラー情報を取得するには、GetLastError関数を使います。

ミューテックスが名前つきミューテックスであり、かつ、そのオブジェクトがこの関数の呼び出しよりも前に存在していた場合、戻り値は既存のオブジェクトのハンドルとなり、直後に呼び出すGetLastError関数は183 (ERROR_ALREADY_EXISTS) を返します。この場合、bInitialOwnerパラメータは無視され、呼び出しスレッドには所有権が与えられません。ただし、呼び出しスレッドが制限されたアクセス権を持つ場合は、関数呼び出しは5 (ERROR_ACCESS_DENIED) で失敗するため、呼び出し側はOpenMutex関数を使用する必要があります。

解説

CreateMutex関数が返すハンドルはMUTEX_ALL_ACCESSアクセス権を持ちます。このアクセス権は、呼び出し側がアクセスを認められている場合に、ミューテックスオブジェクトへのハンドルを必要とするすべての関数で使用することができます。ミューテックスがあるサービスまたはある別のユーザーを偽装しているスレッドから作成されている場合、ミューテックスを作成する際にそのミューテックスにセキュリティ記述子を適用するか、デフォルトのDACLを変更して作成プロセスに対するデフォルトのセキュリティ記述子を変更することができます。

名前つきミューテックスを使用して、アプリケーションが単一のインスタンスのみ存在するように制限する場合、悪意のあるユーザが先にこのミューテックスを作成して、アプリケーションの実行を妨げる可能性があります。このような状況を防ぐには、ランダムな名前つきミューテックスを作成してその名前を保存しておき、認可されたユーザのみがそれを取得できるようにしておきます。別の方法として、この目的のためにファイルを使用することができます。アプリケーションのインスタンスをユーザごとに1つのみに制限するには、ユーザーのprofileディレクトリにロックされたファイルを作成します。

呼び出しプロセスの任意のスレッドは、待機関数 (WaitForSingleObject関数など) の呼び出しでミューテックスオブジェクトのハンドルを指定することができます。複数オブジェクトの待機関数では、指定されたオブジェクトのいずれか1つまたはすべてがシグナル状態となったときに制御を返すように指示することができます。待機関数が制御を返すと、待機中のスレッドは待機が解除されて処理を続行することができるようになります。

ミューテックスオブジェクトがいずれのスレッドにも所有されていないときに、そのオブジェクトはシグナル状態になります。作成スレッドはbInitialOwnerフラグを使用して、ミューテックスの所有権を直ちに要求することができます。ミューテックスがシグナル状態のとき、1つの待機スレッドが所有権を与えられ、そのミューテックスの状態は非シグナル状態に変更され、待機関数が制御を返します。同時にただ1つのスレッドのみがミューテックスの所有権を得ることができます。所有スレッドはReleaseMutex関数を使用して所有権を解放することができます。

ミューテックスを所有しているスレッドは、同一のミューテックスに対して繰り返し待機関数呼び出しても実行がブロックされることはありません。一般に、同一のミューテックスを繰り返し待機することはありませんが、このメカニズムにより、スレッドがすでに所有しているミューテックスを待機することでデッドロックに陥ることを防ぎます。ただし、ミューテックスの所有権を解放するには、スレッドは待機条件を満たした回数のそれぞれに対して1度ずつReleaseMutexを呼び出さなくてはなりません。

複数のプロセスがCreateMutex関数を呼び出して同一の名前付きオブジェクトを作成することができます。この場合、最初のプロセスがミューテックスを実際に作成し、十分なアクセス権を持つ以降のプロセスは単に既存のミューテックスのハンドルをオープンします。これにより、複数プロセスが同一のミューテックスを作成することができるようにした上で、作成プロセスが最初に開始することを保証する責任からユーザーを解放します。この手法を使用するときは、bInitialOwnerフラグに0 (FALSE) を指定すべきです。さもないと、どのスレッドが最初に所有権をもっているのかを判別することが難しくなる可能性があります。

複数のプロセスが同一のミューテックスオブジェクトのハンドルを保持し、そのオブジェクトを使用することによって、プロセス間の同期を行うことができます。以下に列挙するオブジェクト共有メカニズムを使用することができます。

ハンドルをクローズするにはCloseHandle関数を使います。プロセスの終了時には、システムは自動的にハンドルをクローズします。最後のハンドルがクローズされると、ミューテックスオブジェクトは破棄されます。

対応情報

Windows 95 以降 / Windows NT 3.1 以降