Mutex クラス
アセンブリ: mscorlib (mscorlib.dll 内)


![]() |
---|
放棄されたミューテックスは、コードに深刻なエラーが存在することを意味します。スレッドがミューテックスを解放せずに終了すると、ミューテックスによって保護されるデータ構造の状態に不整合が生じることがあります。ミューテックスの所有権を要求する次のスレッドが、データ構造の整合性を検証できる場合、この例外を処理して続行できます。 |
ミューテックスには、ローカル ミューテックスと名前付きシステム ミューテックスの 2 種類があります。名前を受け入れるコンストラクタを使用して Mutex オブジェクトを作成した場合、オブジェクトはその名前のオペレーティング システム オブジェクトに関連付けられます。名前付きシステム ミューテックスはオペレーティング システム全体から参照でき、プロセスの動作を同期するために使用できます。同じ名前付きシステム ミューテックスを表す複数の Mutex オブジェクトを作成できます。また、OpenExisting メソッドを使用すると、既存の名前付きシステム ミューテックスを開くことができます。
ローカル ミューテックスはプロセス内のみに存在します。これは、ローカル Mutex オブジェクトへの参照を持つプロセス内のすべてのスレッドで使用できます。各 Mutex オブジェクトは個別のローカル ミューテックスです。

' This example shows how a Mutex is used to synchronize access ' to a protected resource. Unlike Monitor, Mutex can be used with ' WaitHandle.WaitAll and WaitAny, and can be passed across ' AppDomain boundaries. Imports System Imports System.Threading Imports Microsoft.VisualBasic Class Test ' Create a new Mutex. The creating thread does not own the ' Mutex. Private Shared mut As New Mutex() Private Const numIterations As Integer = 1 Private Const numThreads As Integer = 3 <MTAThread> _ Shared Sub Main() ' Create the threads that will use the protected resource. Dim i As Integer For i = 1 To numThreads Dim myThread As New Thread(AddressOf MyThreadProc) myThread.Name = [String].Format("Thread{0}", i) myThread.Start() Next i ' The main thread exits, but the application continues to ' run until all foreground threads have exited. End Sub 'Main Private Shared Sub MyThreadProc() Dim i As Integer For i = 1 To numIterations UseResource() Next i End Sub 'MyThreadProc ' This method represents a resource that must be synchronized ' so that only one thread at a time can enter. Private Shared Sub UseResource() ' Wait until it is safe to enter. mut.WaitOne() Console.WriteLine("{0} has entered protected area", _ Thread.CurrentThread.Name) ' Place code to access non-reentrant resources here. ' Simulate some work Thread.Sleep(500) Console.WriteLine("{0} is leaving protected area" & vbCrLf, _ Thread.CurrentThread.Name) ' Release Mutex. mut.ReleaseMutex() End Sub 'UseResource End Class 'MyMainClass
// This example shows how a Mutex is used to synchronize access // to a protected resource. Unlike Monitor, Mutex can be used with // WaitHandle.WaitAll and WaitAny, and can be passed across // AppDomain boundaries. using System; using System.Threading; class Test { // Create a new Mutex. The creating thread does not own the // Mutex. private static Mutex mut = new Mutex(); private const int numIterations = 1; private const int numThreads = 3; static void Main() { // Create the threads that will use the protected resource. for(int i = 0; i < numThreads; i++) { Thread myThread = new Thread(new ThreadStart(MyThreadProc)); myThread.Name = String.Format("Thread{0}", i + 1); myThread.Start(); } // The main thread exits, but the application continues to // run until all foreground threads have exited. } private static void MyThreadProc() { for(int i = 0; i < numIterations; i++) { UseResource(); } } // This method represents a resource that must be synchronized // so that only one thread at a time can enter. private static void UseResource() { // Wait until it is safe to enter. mut.WaitOne(); Console.WriteLine("{0} has entered the protected area", Thread.CurrentThread.Name); // Place code to access non-reentrant resources here. // Simulate some work. Thread.Sleep(500); Console.WriteLine("{0} is leaving the protected area\r\n", Thread.CurrentThread.Name); // Release the Mutex. mut.ReleaseMutex(); } }
// This example shows how a Mutex is used to synchronize access // to a protected resource. Unlike Monitor, Mutex can be used with // WaitHandle.WaitAll and WaitAny, and can be passed across // AppDomain boundaries. using namespace System; using namespace System::Threading; const int numIterations = 1; const int numThreads = 3; ref class Test { public: // Create a new Mutex. The creating thread does not own the // Mutex. static Mutex^ mut = gcnew Mutex; static void MyThreadProc() { for ( int i = 0; i < numIterations; i++ ) { UseResource(); } } private: // This method represents a resource that must be synchronized // so that only one thread at a time can enter. static void UseResource() { //Wait until it is OK to enter. mut->WaitOne(); Console::WriteLine( "{0} has entered protected the area", Thread::CurrentThread->Name ); // Place code to access non-reentrant resources here. // Simulate some work. Thread::Sleep( 500 ); Console::WriteLine( "{0} is leaving protected the area\r\n", Thread::CurrentThread->Name ); // Release the Mutex. mut->ReleaseMutex(); } }; int main() { // Create the threads that will use the protected resource. for ( int i = 0; i < numThreads; i++ ) { Thread^ myThread = gcnew Thread( gcnew ThreadStart( Test::MyThreadProc ) ); myThread->Name = String::Format( "Thread {0}", i + 1 ); myThread->Start(); } // The main thread exits, but the application continues to // run until all foreground threads have exited. }
// This example shows how a Mutex is used to synchronize access // to a protected resource. Unlike Monitor, Mutex can be used with // WaitHandle.WaitAll and WaitAny, and can be passed across // AppDomain boundaries. import System.*; import System.Threading.*; import System.Threading.Thread; class Test { // Create a new Mutex. The creating thread does not own the // Mutex. private static Mutex mut = new Mutex(); private static int numIterations = 1; private static int numThreads = 3; public static void main(String[] args) { // Create the threads that will use the protected resource. for (int i = 0; i < numThreads; i++) { Thread myThread = new Thread(new ThreadStart(MyThreadProc)); myThread.set_Name(String.Format("Thread{0}", String.valueOf(i + 1))); myThread.Start(); } } //main // The main thread exits, but the application continues to // run until all foreground threads have exited. private static void MyThreadProc() { for (int i = 0; i < numIterations; i++) { UseResource(); } } //MyThreadProc // This method represents a resource that must be synchronized // so that only one thread at a time can enter. private static void UseResource() { // Wait until it is safe to enter. mut.WaitOne(); Console.WriteLine("{0} has entered the protected area", Thread.get_CurrentThread().get_Name()); // Place code to access non-reentrant resources here. // Simulate some work. Thread.Sleep(500); Console.WriteLine("{0} is leaving the protected area\r\n", Thread.get_CurrentThread().get_Name()); // Release the Mutex. mut.ReleaseMutex(); } //UseResource } //Test

System.MarshalByRefObject
System.Threading.WaitHandle
System.Threading.Mutex


Windows 98, Windows 2000 SP4, Windows CE, Windows Millennium Edition, Windows Mobile for Pocket PC, Windows Mobile for Smartphone, Windows Server 2003, Windows XP Media Center Edition, Windows XP Professional x64 Edition, Windows XP SP2, Windows XP Starter Edition
開発プラットフォームの中には、.NET Framework によってサポートされていないバージョンがあります。サポートされているバージョンについては、「システム要件」を参照してください。


Mutex コンストラクタ ()
アセンブリ: mscorlib (mscorlib.dll 内)


このコンストラクタ オーバーロードを呼び出すことは、Mutex(Boolean) コンストラクタ オーバーロードを呼び出してミューテックスの初期所有権に false を指定することと同じです。つまり、呼び出し元のスレッドはミューテックスを所有していません。

ローカル Mutex オブジェクトを使用して、保護されたリソースへのアクセスを同期する方法を次のコード例に示します。ミューテックスを作成するスレッドは、初期状態ではミューテックスを所有していません。
' This example shows how a Mutex is used to synchronize access ' to a protected resource. Unlike Monitor, Mutex can be used with ' WaitHandle.WaitAll and WaitAny, and can be passed across ' AppDomain boundaries. Imports System Imports System.Threading Imports Microsoft.VisualBasic Class Test ' Create a new Mutex. The creating thread does not own the ' Mutex. Private Shared mut As New Mutex() Private Const numIterations As Integer = 1 Private Const numThreads As Integer = 3 <MTAThread> _ Shared Sub Main() ' Create the threads that will use the protected resource. Dim i As Integer For i = 1 To numThreads Dim myThread As New Thread(AddressOf MyThreadProc) myThread.Name = [String].Format("Thread{0}", i) myThread.Start() Next i ' The main thread exits, but the application continues to ' run until all foreground threads have exited. End Sub 'Main Private Shared Sub MyThreadProc() Dim i As Integer For i = 1 To numIterations UseResource() Next i End Sub 'MyThreadProc ' This method represents a resource that must be synchronized ' so that only one thread at a time can enter. Private Shared Sub UseResource() ' Wait until it is safe to enter. mut.WaitOne() Console.WriteLine("{0} has entered protected area", _ Thread.CurrentThread.Name) ' Place code to access non-reentrant resources here. ' Simulate some work Thread.Sleep(500) Console.WriteLine("{0} is leaving protected area" & vbCrLf, _ Thread.CurrentThread.Name) ' Release Mutex. mut.ReleaseMutex() End Sub 'UseResource End Class 'MyMainClass
// This example shows how a Mutex is used to synchronize access // to a protected resource. Unlike Monitor, Mutex can be used with // WaitHandle.WaitAll and WaitAny, and can be passed across // AppDomain boundaries. using System; using System.Threading; class Test { // Create a new Mutex. The creating thread does not own the // Mutex. private static Mutex mut = new Mutex(); private const int numIterations = 1; private const int numThreads = 3; static void Main() { // Create the threads that will use the protected resource. for(int i = 0; i < numThreads; i++) { Thread myThread = new Thread(new ThreadStart(MyThreadProc)); myThread.Name = String.Format("Thread{0}", i + 1); myThread.Start(); } // The main thread exits, but the application continues to // run until all foreground threads have exited. } private static void MyThreadProc() { for(int i = 0; i < numIterations; i++) { UseResource(); } } // This method represents a resource that must be synchronized // so that only one thread at a time can enter. private static void UseResource() { // Wait until it is safe to enter. mut.WaitOne(); Console.WriteLine("{0} has entered the protected area", Thread.CurrentThread.Name); // Place code to access non-reentrant resources here. // Simulate some work. Thread.Sleep(500); Console.WriteLine("{0} is leaving the protected area\r\n", Thread.CurrentThread.Name); // Release the Mutex. mut.ReleaseMutex(); } }
// This example shows how a Mutex is used to synchronize access // to a protected resource. Unlike Monitor, Mutex can be used with // WaitHandle.WaitAll and WaitAny, and can be passed across // AppDomain boundaries. using namespace System; using namespace System::Threading; const int numIterations = 1; const int numThreads = 3; ref class Test { public: // Create a new Mutex. The creating thread does not own the // Mutex. static Mutex^ mut = gcnew Mutex; static void MyThreadProc() { for ( int i = 0; i < numIterations; i++ ) { UseResource(); } } private: // This method represents a resource that must be synchronized // so that only one thread at a time can enter. static void UseResource() { //Wait until it is OK to enter. mut->WaitOne(); Console::WriteLine( "{0} has entered protected the area", Thread::CurrentThread->Name ); // Place code to access non-reentrant resources here. // Simulate some work. Thread::Sleep( 500 ); Console::WriteLine( "{0} is leaving protected the area\r\n", Thread::CurrentThread->Name ); // Release the Mutex. mut->ReleaseMutex(); } }; int main() { // Create the threads that will use the protected resource. for ( int i = 0; i < numThreads; i++ ) { Thread^ myThread = gcnew Thread( gcnew ThreadStart( Test::MyThreadProc ) ); myThread->Name = String::Format( "Thread {0}", i + 1 ); myThread->Start(); } // The main thread exits, but the application continues to // run until all foreground threads have exited. }
// This example shows how a Mutex is used to synchronize access // to a protected resource. Unlike Monitor, Mutex can be used with // WaitHandle.WaitAll and WaitAny, and can be passed across // AppDomain boundaries. import System.*; import System.Threading.*; import System.Threading.Thread; class Test { // Create a new Mutex. The creating thread does not own the // Mutex. private static Mutex mut = new Mutex(); private static int numIterations = 1; private static int numThreads = 3; public static void main(String[] args) { // Create the threads that will use the protected resource. for (int i = 0; i < numThreads; i++) { Thread myThread = new Thread(new ThreadStart(MyThreadProc)); myThread.set_Name(String.Format("Thread{0}", String.valueOf(i + 1))); myThread.Start(); } } //main // The main thread exits, but the application continues to // run until all foreground threads have exited. private static void MyThreadProc() { for (int i = 0; i < numIterations; i++) { UseResource(); } } //MyThreadProc // This method represents a resource that must be synchronized // so that only one thread at a time can enter. private static void UseResource() { // Wait until it is safe to enter. mut.WaitOne(); Console.WriteLine("{0} has entered the protected area", Thread.get_CurrentThread().get_Name()); // Place code to access non-reentrant resources here. // Simulate some work. Thread.Sleep(500); Console.WriteLine("{0} is leaving the protected area\r\n", Thread.get_CurrentThread().get_Name()); // Release the Mutex. mut.ReleaseMutex(); } //UseResource } //Test

Windows 98, Windows 2000 SP4, Windows CE, Windows Millennium Edition, Windows Mobile for Pocket PC, Windows Mobile for Smartphone, Windows Server 2003, Windows XP Media Center Edition, Windows XP Professional x64 Edition, Windows XP SP2, Windows XP Starter Edition
開発プラットフォームの中には、.NET Framework によってサポートされていないバージョンがあります。サポートされているバージョンについては、「システム要件」を参照してください。


Mutex コンストラクタ (Boolean)
アセンブリ: mscorlib (mscorlib.dll 内)


ローカル Mutex オブジェクトを使用して、保護されたリソースへのアクセスを同期する方法を次のコード例に示します。Mutex を作成するスレッドは、初期状態でミューテックスを所有しています。
' This example shows how a Mutex is used to synchronize access ' to a protected resource. Unlike Monitor, Mutex can be used with ' WaitHandle.WaitAll and WaitAny, and can be passed across ' AppDomain boundaries. Imports System Imports System.Threading Imports Microsoft.VisualBasic Class Test ' Create a new Mutex. The creating thread owns the ' Mutex. Private Shared mut As New Mutex(True) Private Const numIterations As Integer = 1 Private Const numThreads As Integer = 3 <MTAThread> _ Shared Sub Main() ' Create the threads that will use the protected resource. Dim i As Integer For i = 1 To numThreads Dim myThread As New Thread(AddressOf MyThreadProc) myThread.Name = [String].Format("Thread{0}", i) myThread.Start() Next i ' Wait one second before allowing other threads to ' acquire the Mutex. Console.WriteLine("Creating thread owns the Mutex.") Thread.Sleep(1000) Console.WriteLine("Creating thread releases the Mutex." & vbCrLf) mut.ReleaseMutex() End Sub 'Main Private Shared Sub MyThreadProc() Dim i As Integer For i = 1 To numIterations UseResource() Next i End Sub 'MyThreadProc ' This method represents a resource that must be synchronized ' so that only one thread at a time can enter. Private Shared Sub UseResource() ' Wait until it is safe to enter. mut.WaitOne() Console.WriteLine("{0} has entered protected area", _ Thread.CurrentThread.Name) ' Place code to access non-reentrant resources here. ' Simulate some work Thread.Sleep(500) Console.WriteLine("{0} is leaving protected area" & vbCrLf, _ Thread.CurrentThread.Name) ' Release Mutex. mut.ReleaseMutex() End Sub 'UseResource End Class 'MyMainClass
// This example shows how a Mutex is used to synchronize access // to a protected resource. Unlike Monitor, Mutex can be used with // WaitHandle.WaitAll and WaitAny, and can be passed across // AppDomain boundaries. using System; using System.Threading; class Test { // Create a new Mutex. The creating thread owns the // Mutex. private static Mutex mut = new Mutex(true); private const int numIterations = 1; private const int numThreads = 3; static void Main() { // Create the threads that will use the protected resource. for(int i = 0; i < numThreads; i++) { Thread myThread = new Thread(new ThreadStart(MyThreadProc)); myThread.Name = String.Format("Thread{0}", i + 1); myThread.Start(); } // Wait one second before allowing other threads to // acquire the Mutex. Console.WriteLine("Creating thread owns the Mutex."); Thread.Sleep(1000); Console.WriteLine("Creating thread releases the Mutex.\r\n"); mut.ReleaseMutex(); } private static void MyThreadProc() { for(int i = 0; i < numIterations; i++) { UseResource(); } } // This method represents a resource that must be synchronized // so that only one thread at a time can enter. private static void UseResource() { // Wait until it is safe to enter. mut.WaitOne(); Console.WriteLine("{0} has entered the protected area", Thread.CurrentThread.Name); // Place code to access non-reentrant resources here. // Simulate some work. Thread.Sleep(500); Console.WriteLine("{0} is leaving the protected area\r\n", Thread.CurrentThread.Name); // Release the Mutex. mut.ReleaseMutex(); } }
// This example shows how a Mutex is used to synchronize access // to a protected resource. Unlike Monitor, Mutex can be used with // WaitHandle.WaitAll and WaitAny, and can be passed across // AppDomain boundaries. using namespace System; using namespace System::Threading; const int numIterations = 1; const int numThreads = 3; ref class Test { public: // Create a new Mutex. The creating thread owns the // Mutex. static Mutex^ mut = gcnew Mutex( true ); static void MyThreadProc() { for ( int i = 0; i < numIterations; i++ ) { UseResource(); } } private: // This method represents a resource that must be synchronized // so that only one thread at a time can enter. static void UseResource() { //Wait until it is OK to enter. mut->WaitOne(); Console::WriteLine( "{0} has entered protected the area", Thread::CurrentThread->Name ); // Place code to access non-reentrant resources here. // Simulate some work. Thread::Sleep( 500 ); Console::WriteLine( "{0} is leaving protected the area\r\n", Thread::CurrentThread->Name ); // Release the Mutex. mut->ReleaseMutex(); } }; int main() { // Initialize the Mutex. Mutex^ mut = Test::mut; // Create the threads that will use the protected resource. for ( int i = 0; i < numThreads; i++ ) { Thread^ myThread = gcnew Thread( gcnew ThreadStart( Test::MyThreadProc ) ); myThread->Name = String::Format( "Thread {0}", i + 1 ); myThread->Start(); } // Wait one second before allowing other threads to // acquire the Mutex. Console::WriteLine( "Creating thread owns the Mutex." ); Thread::Sleep( 1000 ); Console::WriteLine( "Creating thread releases the Mutex.\r\n" ); mut->ReleaseMutex(); }
// This example shows how a Mutex is used to synchronize access // to a protected resource. Unlike Monitor, Mutex can be used with // WaitHandle.WaitAll and WaitAny, and can be passed across // AppDomain boundaries. import System.*; import System.Threading.* ; import System.Threading.Thread; class Test { // Create a new Mutex. The creating thread owns the // Mutex. private static Mutex mut = new Mutex(true); private static int numIterations = 1; private static int numThreads = 3; public static void main(String[] args) { // Create the threads that will use the protected resource. for (int i = 0; i < numThreads; i++) { Thread myThread = new Thread(new ThreadStart(MyThreadProc)); myThread.set_Name(String.Format("Thread{0}", String.valueOf(i + 1))); myThread.Start(); } // Wait one second before allowing other threads to // acquire the Mutex. Console.WriteLine("Creating thread owns the Mutex."); Thread.Sleep(1000); Console.WriteLine("Creating thread releases the Mutex.\r\n"); mut.ReleaseMutex(); } //main private static void MyThreadProc() { for (int i = 0; i < numIterations; i++) { UseResource(); } } //MyThreadProc // This method represents a resource that must be synchronized // so that only one thread at a time can enter. private static void UseResource() { // Wait until it is safe to enter. mut.WaitOne(); Console.WriteLine("{0} has entered the protected area", Thread.get_CurrentThread().get_Name()); // Place code to access non-reentrant resources here. // Simulate some work. Thread.Sleep(500); Console.WriteLine("{0} is leaving the protected area\r\n", Thread.get_CurrentThread().get_Name()); // Release the Mutex. mut.ReleaseMutex(); } //UseResource } //Test

Windows 98, Windows 2000 SP4, Windows CE, Windows Millennium Edition, Windows Mobile for Pocket PC, Windows Mobile for Smartphone, Windows Server 2003, Windows XP Media Center Edition, Windows XP Professional x64 Edition, Windows XP SP2, Windows XP Starter Edition
開発プラットフォームの中には、.NET Framework によってサポートされていないバージョンがあります。サポートされているバージョンについては、「システム要件」を参照してください。


Mutex コンストラクタ (Boolean, String, Boolean, MutexSecurity)
アセンブリ: mscorlib (mscorlib.dll 内)

Public Sub New ( _ initiallyOwned As Boolean, _ name As String, _ <OutAttribute> ByRef createdNew As Boolean, _ mutexSecurity As MutexSecurity _ )
Dim initiallyOwned As Boolean Dim name As String Dim createdNew As Boolean Dim mutexSecurity As MutexSecurity Dim instance As New Mutex(initiallyOwned, name, createdNew, mutexSecurity)
public: Mutex ( bool initiallyOwned, String^ name, [OutAttribute] bool% createdNew, MutexSecurity^ mutexSecurity )
public Mutex ( boolean initiallyOwned, String name, /** @attribute OutAttribute() */ /** @ref */ boolean createdNew, MutexSecurity mutexSecurity )
public function Mutex ( initiallyOwned : boolean, name : String, createdNew : boolean, mutexSecurity : MutexSecurity )
- initiallyOwned
この呼び出しの結果として名前付きシステム ミューテックスが作成される場合に、呼び出し元スレッドに名前付きシステム ミューテックスの初期所有権を付与する場合は true。それ以外の場合は false。


name が null 参照 (Visual Basic では Nothing) ではなく initiallyOwned が true の場合、呼び出し元スレッドは、呼び出し後に createdNew が true である場合にのみ名前付きミューテックスを所有します。それ以外の場合、スレッドは WaitOne メソッドを呼び出すことによってミューテックスを要求できます。
このコンストラクタは、名前付きシステム ミューテックスの作成時にミューテックスにアクセス制御セキュリティを適用して、他のコードがミューテックスを制御できないようにするために使用します。
このコンストラクタは、名前付きシステム ミューテックスを表す Mutex オブジェクトを初期化します。同じ名前付きシステム ミューテックスを表す複数の Mutex オブジェクトを作成できます。
名前付きシステム ミューテックスが存在しない場合、指定したアクセス制御セキュリティで名前付きシステム ミューテックスが作成されます。名前付きシステム ミューテックスが存在する場合、指定したアクセス制御セキュリティは無視されます。
![]() |
---|
mutexSecurity が現在のユーザーに対して一部のアクセス権を拒否していたり、アクセス権を付与できなかったりした場合でも、呼び出し元は新しく作成した Mutex オブジェクトを完全に制御します。ただし、現在のユーザーがコンストラクタまたは OpenExisting メソッドを使用して、同じ名前付きミューテックスを表す別の Mutex オブジェクトを取得しようとした場合は、Windows のアクセス制御セキュリティが適用されます。 |
名前付きミューテックスがアクセス制御セキュリティで既に作成されていて、呼び出し元に MutexRights.FullControl がない場合は、例外がスローされます。スレッドの動作を同期するために必要な権限でのみ既存の名前付きミューテックスを開く方法については、OpenExisting メソッドに関するトピックを参照してください。
name に null 参照 (Visual Basic では Nothing) または空の文字列を指定すると、Mutex(Boolean) コンストラクタを呼び出した場合と同様に、ローカル ミューテックスが作成されます。この場合、createdNew は常に true です。

アクセス制御セキュリティを使用した名前付きミューテックスのプロセス間の動作をデモンストレーションするコード例を次に示します。この例では、OpenExisting(String) メソッド オーバーロードを使用して、名前付きミューテックスが存在するかどうかをテストしています。
ミューテックスが存在しない場合、初期所有権と、現在のユーザーによるミューテックスの使用を拒否し、ミューテックスに対する読み取りと変更のアクセス許可のみ付与するアクセス制御セキュリティでミューテックスが作成されます。
2 つのコマンド ウィンドウからコンパイルした例を実行すると、2 番目のコピーは OpenExisting(String) の呼び出しでアクセス違反例外をスローします。例外がキャッチされると、OpenExisting(String,MutexRights) メソッド オーバーロードを使用し、アクセス許可の読み取りと変更に必要な権限で、ミューテックスを開きます。
アクセス許可が変更された後、入力と解放に必要な権限でミューテックスが開かれます。3 つ目のコマンド ウィンドウからコンパイル済みの例を実行する場合、新しいアクセス許可を使用して実行されます。
Imports System Imports System.Threading Imports System.Security.AccessControl Friend Class Example <MTAThread> _ Friend Shared Sub Main() Const mutexName As String = "MutexExample4" Dim m As Mutex = Nothing Dim doesNotExist as Boolean = False Dim unauthorized As Boolean = False ' The value of this variable is set by the mutex ' constructor. It is True if the named system mutex was ' created, and False if the named mutex already existed. ' Dim mutexWasCreated As Boolean ' Attempt to open the named mutex. Try ' Open the mutex with (MutexRights.Synchronize Or ' MutexRights.Modify), to enter and release the ' named mutex. ' m = Mutex.OpenExisting(mutexName) Catch ex As WaitHandleCannotBeOpenedException Console.WriteLine("Mutex does not exist.") doesNotExist = True Catch ex As UnauthorizedAccessException Console.WriteLine("Unauthorized access: {0}", ex.Message) unauthorized = True End Try ' There are three cases: (1) The mutex does not exist. ' (2) The mutex exists, but the current user doesn't ' have access. (3) The mutex exists and the user has ' access. ' If doesNotExist Then ' The mutex does not exist, so create it. ' Create an access control list (ACL) that denies the ' current user the right to enter or release the ' mutex, but allows the right to read and change ' security information for the mutex. ' Dim user As String = Environment.UserDomainName _ & "\" & Environment.UserName Dim mSec As New MutexSecurity() Dim rule As New MutexAccessRule(user, _ MutexRights.Synchronize Or MutexRights.Modify, _ AccessControlType.Deny) mSec.AddAccessRule(rule) rule = New MutexAccessRule(user, _ MutexRights.ReadPermissions Or _ MutexRights.ChangePermissions, _ AccessControlType.Allow) mSec.AddAccessRule(rule) ' Create a Mutex object that represents the system ' mutex named by the constant 'mutexName', with ' initial ownership for this thread, and with the ' specified security access. The Boolean value that ' indicates creation of the underlying system object ' is placed in mutexWasCreated. ' m = New Mutex(True, mutexName, mutexWasCreated, mSec) ' If the named system mutex was created, it can be ' used by the current instance of this program, even ' though the current user is denied access. The current ' program owns the mutex. Otherwise, exit the program. ' If mutexWasCreated Then Console.WriteLine("Created the mutex.") Else Console.WriteLine("Unable to create the mutex.") Return End If ElseIf unauthorized Then ' Open the mutex to read and change the access control ' security. The access control security defined above ' allows the current user to do this. ' Try m = Mutex.OpenExisting(mutexName, _ MutexRights.ReadPermissions Or _ MutexRights.ChangePermissions) ' Get the current ACL. This requires ' MutexRights.ReadPermissions. Dim mSec As MutexSecurity = m.GetAccessControl() Dim user As String = Environment.UserDomainName _ & "\" & Environment.UserName ' First, the rule that denied the current user ' the right to enter and release the mutex must ' be removed. Dim rule As New MutexAccessRule(user, _ MutexRights.Synchronize Or MutexRights.Modify, _ AccessControlType.Deny) mSec.RemoveAccessRule(rule) ' Now grant the user the correct rights. ' rule = New MutexAccessRule(user, _ MutexRights.Synchronize Or MutexRights.Modify, _ AccessControlType.Allow) mSec.AddAccessRule(rule) ' Update the ACL. This requires ' MutexRights.ChangePermissions. m.SetAccessControl(mSec) Console.WriteLine("Updated mutex security.") ' Open the mutex with (MutexRights.Synchronize ' Or MutexRights.Modify), the rights required to ' enter and release the mutex. ' m = Mutex.OpenExisting(mutexName) Catch ex As UnauthorizedAccessException Console.WriteLine("Unable to change permissions: {0}", _ ex.Message) Return End Try End If ' If this program created the mutex, it already owns ' the mutex. ' If Not mutexWasCreated Then ' Enter the mutex, and hold it until the program ' exits. ' Try Console.WriteLine("Wait for the mutex.") m.WaitOne() Console.WriteLine("Entered the mutex.") Catch ex As UnauthorizedAccessException Console.WriteLine("Unauthorized access: {0}", _ ex.Message) End Try End If Console.WriteLine("Press the Enter key to exit.") Console.ReadLine() m.ReleaseMutex() End Sub End Class
using System; using System.Threading; using System.Security.AccessControl; internal class Example { internal static void Main() { const string mutexName = "MutexExample4"; Mutex m = null; bool doesNotExist = false; bool unauthorized = false; // The value of this variable is set by the mutex // constructor. It is true if the named system mutex was // created, and false if the named mutex already existed. // bool mutexWasCreated = false; // Attempt to open the named mutex. try { // Open the mutex with (MutexRights.Synchronize | // MutexRights.Modify), to enter and release the // named mutex. // m = Mutex.OpenExisting(mutexName); } catch(WaitHandleCannotBeOpenedException) { Console.WriteLine("Mutex does not exist."); doesNotExist = true; } catch(UnauthorizedAccessException ex) { Console.WriteLine("Unauthorized access: {0}", ex.Message); unauthorized = true; } // There are three cases: (1) The mutex does not exist. // (2) The mutex exists, but the current user doesn't // have access. (3) The mutex exists and the user has // access. // if (doesNotExist) { // The mutex does not exist, so create it. // Create an access control list (ACL) that denies the // current user the right to enter or release the // mutex, but allows the right to read and change // security information for the mutex. // string user = Environment.UserDomainName + "\\" + Environment.UserName; MutexSecurity mSec = new MutexSecurity(); MutexAccessRule rule = new MutexAccessRule(user, MutexRights.Synchronize | MutexRights.Modify, AccessControlType.Deny); mSec.AddAccessRule(rule); rule = new MutexAccessRule(user, MutexRights.ReadPermissions | MutexRights.ChangePermissions, AccessControlType.Allow); mSec.AddAccessRule(rule); // Create a Mutex object that represents the system // mutex named by the constant 'mutexName', with // initial ownership for this thread, and with the // specified security access. The Boolean value that // indicates creation of the underlying system object // is placed in mutexWasCreated. // m = new Mutex(true, mutexName, out mutexWasCreated, mSec); // If the named system mutex was created, it can be // used by the current instance of this program, even // though the current user is denied access. The current // program owns the mutex. Otherwise, exit the program. // if (mutexWasCreated) { Console.WriteLine("Created the mutex."); } else { Console.WriteLine("Unable to create the mutex."); return; } } else if (unauthorized) { // Open the mutex to read and change the access control // security. The access control security defined above // allows the current user to do this. // try { m = Mutex.OpenExisting(mutexName, MutexRights.ReadPermissions | MutexRights.ChangePermissions); // Get the current ACL. This requires // MutexRights.ReadPermissions. MutexSecurity mSec = m.GetAccessControl(); string user = Environment.UserDomainName + "\\" + Environment.UserName; // First, the rule that denied the current user // the right to enter and release the mutex must // be removed. MutexAccessRule rule = new MutexAccessRule(user, MutexRights.Synchronize | MutexRights.Modify, AccessControlType.Deny); mSec.RemoveAccessRule(rule); // Now grant the user the correct rights. // rule = new MutexAccessRule(user, MutexRights.Synchronize | MutexRights.Modify, AccessControlType.Allow); mSec.AddAccessRule(rule); // Update the ACL. This requires // MutexRights.ChangePermissions. m.SetAccessControl(mSec); Console.WriteLine("Updated mutex security."); // Open the mutex with (MutexRights.Synchronize // | MutexRights.Modify), the rights required to // enter and release the mutex. // m = Mutex.OpenExisting(mutexName); } catch(UnauthorizedAccessException ex) { Console.WriteLine("Unable to change permissions: {0}", ex.Message); return; } } // If this program created the mutex, it already owns // the mutex. // if (!mutexWasCreated) { // Enter the mutex, and hold it until the program // exits. // try { Console.WriteLine("Wait for the mutex."); m.WaitOne(); Console.WriteLine("Entered the mutex."); } catch(UnauthorizedAccessException ex) { Console.WriteLine("Unauthorized access: {0}", ex.Message); } } Console.WriteLine("Press the Enter key to exit."); Console.ReadLine(); m.ReleaseMutex(); } }
using namespace System; using namespace System::Threading; using namespace System::Security::AccessControl; using namespace System::Security::Permissions; public ref class Example { public: [SecurityPermissionAttribute(SecurityAction::Demand,Flags=SecurityPermissionFlag::UnmanagedCode)] static void Main() { String^ mutexName = L"MutexExample4"; Mutex^ m = nullptr; bool doesNotExist = false; bool unauthorized = false; // The value of this variable is set by the mutex // constructor. It is true if the named system mutex was // created, and false if the named mutex already existed. // bool mutexWasCreated = false; // Attempt to open the named mutex. try { // Open the mutex with (MutexRights.Synchronize | // MutexRights.Modify), to enter and release the // named mutex. // m = Mutex::OpenExisting( mutexName ); } catch ( WaitHandleCannotBeOpenedException^ ) { Console::WriteLine( L"Mutex does not exist." ); doesNotExist = true; } catch ( UnauthorizedAccessException^ ex ) { Console::WriteLine( L"Unauthorized access: {0}", ex->Message ); unauthorized = true; } // There are three cases: (1) The mutex does not exist. // (2) The mutex exists, but the current user doesn't // have access. (3) The mutex exists and the user has // access. // if ( doesNotExist ) { // The mutex does not exist, so create it. // Create an access control list (ACL) that denies the // current user the right to enter or release the // mutex, but allows the right to read and change // security information for the mutex. // String^ user = String::Concat( Environment::UserDomainName, L"\\" , Environment::UserName ); MutexSecurity^ mSec = gcnew MutexSecurity; MutexAccessRule^ rule = gcnew MutexAccessRule( user, static_cast<MutexRights>( MutexRights::Synchronize | MutexRights::Modify), AccessControlType::Deny ); mSec->AddAccessRule( rule ); rule = gcnew MutexAccessRule( user, static_cast<MutexRights>( MutexRights::ReadPermissions | MutexRights::ChangePermissions), AccessControlType::Allow ); mSec->AddAccessRule( rule ); // Create a Mutex object that represents the system // mutex named by the constant 'mutexName', with // initial ownership for this thread, and with the // specified security access. The Boolean value that // indicates creation of the underlying system object // is placed in mutexWasCreated. // m = gcnew Mutex( true,mutexName, mutexWasCreated,mSec ); // If the named system mutex was created, it can be // used by the current instance of this program, even // though the current user is denied access. The current // program owns the mutex. Otherwise, exit the program. // if ( mutexWasCreated ) { Console::WriteLine( L"Created the mutex." ); } else { Console::WriteLine( L"Unable to create the mutex." ); return; } } else if ( unauthorized ) { // Open the mutex to read and change the access control // security. The access control security defined above // allows the current user to do this. // try { m = Mutex::OpenExisting( mutexName, static_cast<MutexRights>( MutexRights::ReadPermissions | MutexRights::ChangePermissions) ); // Get the current ACL. This requires // MutexRights.ReadPermissions. MutexSecurity^ mSec = m->GetAccessControl(); String^ user = String::Concat( Environment::UserDomainName, L"\\", Environment::UserName ); // First, the rule that denied the current user // the right to enter and release the mutex must // be removed. MutexAccessRule^ rule = gcnew MutexAccessRule( user, static_cast<MutexRights>( MutexRights::Synchronize | MutexRights::Modify), AccessControlType::Deny ); mSec->RemoveAccessRule( rule ); // Now grant the user the correct rights. // rule = gcnew MutexAccessRule( user, static_cast<MutexRights>( MutexRights::Synchronize | MutexRights::Modify), AccessControlType::Allow ); mSec->AddAccessRule( rule ); // Update the ACL. This requires // MutexRights.ChangePermissions. m->SetAccessControl( mSec ); Console::WriteLine( L"Updated mutex security." ); // Open the mutex with (MutexRights.Synchronize // | MutexRights.Modify), the rights required to // enter and release the mutex. // m = Mutex::OpenExisting( mutexName ); } catch ( UnauthorizedAccessException^ ex ) { Console::WriteLine( L"Unable to change permissions: {0}", ex->Message ); return; } } // If this program created the mutex, it already owns // the mutex. // if ( !mutexWasCreated ) { // Enter the mutex, and hold it until the program // exits. // try { Console::WriteLine( L"Wait for the mutex." ); m->WaitOne(); Console::WriteLine( L"Entered the mutex." ); } catch ( UnauthorizedAccessException^ ex ) { Console::WriteLine( L"Unauthorized access: {0}", ex->Message ); } } Console::WriteLine( L"Press the Enter key to exit." ); Console::ReadLine(); m->ReleaseMutex(); } }; int main() { Example::Main(); }


Windows 98, Windows 2000 SP4, Windows Millennium Edition, Windows Server 2003, Windows XP Media Center Edition, Windows XP Professional x64 Edition, Windows XP SP2, Windows XP Starter Edition
開発プラットフォームの中には、.NET Framework によってサポートされていないバージョンがあります。サポートされているバージョンについては、「システム要件」を参照してください。


Mutex コンストラクタ (Boolean, String, Boolean)
アセンブリ: mscorlib (mscorlib.dll 内)

Public Sub New ( _ initiallyOwned As Boolean, _ name As String, _ <OutAttribute> ByRef createdNew As Boolean _ )
Dim initiallyOwned As Boolean Dim name As String Dim createdNew As Boolean Dim instance As New Mutex(initiallyOwned, name, createdNew)
public Mutex ( boolean initiallyOwned, String name, /** @attribute OutAttribute() */ /** @ref */ boolean createdNew )


name が null 参照 (Visual Basic では Nothing) ではなく initiallyOwned が true の場合、呼び出し元スレッドは、呼び出し後に createdNew が true である場合にのみ名前付きミューテックスを所有します。それ以外の場合、スレッドは WaitOne メソッドを呼び出すことによってミューテックスを要求できます。
このコンストラクタは、名前付きシステム ミューテックスを表す Mutex オブジェクトを初期化します。同じ名前付きシステム ミューテックスを表す複数の Mutex オブジェクトを作成できます。
名前付きミューテックスがアクセス制御セキュリティで既に作成されていて、呼び出し元に MutexRights.FullControl 権限がない場合は、例外がスローされます。スレッドの動作を同期するために必要な権限でのみ既存の名前付きミューテックスを開く方法については、OpenExisting メソッドに関するトピックを参照してください。
name に null 参照 (Visual Basic では Nothing) または空の文字列を指定すると、Mutex(Boolean) コンストラクタを呼び出した場合と同様に、ローカル ミューテックスが作成されます。この場合、createdNew は常に true です。

名前付きミューテックスを使用してプロセス間またはスレッド間の通知を行うコード例を次に示します。このプログラムは、複数のコマンド ウィンドウから実行します。各プロセスで、名前付きミューテックス "MyMutex" を表す Mutex オブジェクトが作成されます。名前付きミューテックスはシステム オブジェクトです。この例では、名前付きミューテックスの有効期間が、この名前付きミューテックスを表す Mutex オブジェクトの有効期間によって制限されています。名前付きミューテックスは、最初のプロセスでローカル Mutex オブジェクトが作成されるときに作成され、この名前付きミューテックスを表す Mutex オブジェクトがすべて解放されたときに破棄されます。初期状態では、名前付きミューテックスは最初のプロセスによって所有されています。2 番目のプロセスおよび後続のプロセスは、それ以前のプロセスが名前付きミューテックスを解放するまで待機します。
' This example shows how a named mutex is used to signal between ' processes or threads. ' Run this program from two (or more) command windows. Each process ' creates a Mutex object that represents the named mutex "MyMutex". ' The named mutex is a system object whose lifetime is bounded by the ' lifetimes of the Mutex objects that represent it. The named mutex ' is created when the first process creates its local Mutex; in this ' example, the named mutex is owned by the first process. The named ' mutex is destroyed when all the Mutex objects that represent it ' have been released. ' The second process (and any subsequent process) waits for earlier ' processes to release the named mutex. Imports System Imports System.Threading Public Class Test <MTAThread> _ Public Shared Sub Main() ' Set this variable to false if you do not want to request ' initial ownership of the named mutex. Dim requestInitialOwnership As Boolean = True Dim mutexWasCreated As Boolean ' Request initial ownership of the named mutex by passing ' true for the first parameter. Only one system object named ' "MyMutex" can exist; the local Mutex object represents ' this system object. If "MyMutex" is created by this call, ' then mutexWasCreated contains true; otherwise, it contains ' false. Dim m As New Mutex(requestInitialOwnership, "MyMutex", _ mutexWasCreated) ' This thread owns the mutex only if it both requested ' initial ownership and created the named mutex. Otherwise, ' it can request the named mutex by calling WaitOne. If Not (requestInitialOwnership And mutexWasCreated) Then Console.WriteLine("Waiting for the named mutex.") m.WaitOne() End If ' Once the process has gained control of the named mutex, ' hold onto it until the user presses ENTER. Console.WriteLine("This process owns the named mutex. " _ & "Press ENTER to release the mutex and exit.") Console.ReadLine() ' Call ReleaseMutex to allow other threads to gain control ' of the named mutex. If you keep a reference to the local ' Mutex, you can call WaitOne to request control of the ' named mutex. m.ReleaseMutex() End Sub 'Main End Class 'Test
// This example shows how a named mutex is used to signal between // processes or threads. // Run this program from two (or more) command windows. Each process // creates a Mutex object that represents the named mutex "MyMutex". // The named mutex is a system object whose lifetime is bounded by the // lifetimes of the Mutex objects that represent it. The named mutex // is created when the first process creates its local Mutex; in this // example, the named mutex is owned by the first process. The named // mutex is destroyed when all the Mutex objects that represent it // have been released. // The second process (and any subsequent process) waits for earlier // processes to release the named mutex. using System; using System.Threading; public class Test { public static void Main() { // Set this variable to false if you do not want to request // initial ownership of the named mutex. bool requestInitialOwnership = true; bool mutexWasCreated; // Request initial ownership of the named mutex by passing // true for the first parameter. Only one system object named // "MyMutex" can exist; the local Mutex object represents // this system object. If "MyMutex" is created by this call, // then mutexWasCreated contains true; otherwise, it contains // false. Mutex m = new Mutex(requestInitialOwnership, "MyMutex", out mutexWasCreated); // This thread owns the mutex only if it both requested // initial ownership and created the named mutex. Otherwise , // it can request the named mutex by calling WaitOne. if (!(requestInitialOwnership && mutexWasCreated)) { Console.WriteLine("Waiting for the named mutex."); m.WaitOne(); } // Once the process has gained control of the named mutex, // hold onto it until the user presses ENTER. Console.WriteLine("This process owns the named mutex. " + "Press ENTER to release the mutex and exit."); Console.ReadLine(); // Call ReleaseMutex to allow other threads to gain control // of the named mutex. If you keep a reference to the local // Mutex, you can call WaitOne to request control of the // named mutex. m.ReleaseMutex(); } }
// This example shows how a named mutex is used to signal between // processes or threads. // Run this program from two (or more) command windows. Each process // creates a Mutex object that represents the named mutex "MyMutex". // The named mutex is a system object whose lifetime is bounded by the // lifetimes of the Mutex objects that represent it. The named mutex // is created when the first process creates its local Mutex; in this // example, the named mutex is owned by the first process. The named // mutex is destroyed when all the Mutex objects that represent it // have been released. // The second process (and any subsequent process) waits for earlier // processes to release the named mutex. using namespace System; using namespace System::Threading; int main() { // Set this variable to false if you do not want to request // initial ownership of the named mutex. bool requestInitialOwnership = true; bool mutexWasCreated; // Request initial ownership of the named mutex by passing // true for the first parameter. Only one system object named // "MyMutex" can exist; the local Mutex object represents // this system object. If "MyMutex" is created by this call, // then mutexWasCreated contains true; otherwise, it contains // false. Mutex^ m = gcnew Mutex( requestInitialOwnership, "MyMutex", mutexWasCreated ); // This thread owns the mutex only if it both requested // initial ownership and created the named mutex. Otherwise, // it can request the named mutex by calling WaitOne. if ( !(requestInitialOwnership && mutexWasCreated) ) { Console::WriteLine( "Waiting for the named mutex." ); m->WaitOne(); } // Once the process has gained control of the named mutex, // hold onto it until the user presses ENTER. Console::WriteLine( "This process owns the named mutex. " "Press ENTER to release the mutex and exit." ); Console::ReadLine(); // Call ReleaseMutex to allow other threads to gain control // of the named mutex. If you keep a reference to the local // Mutex, you can call WaitOne to request control of the // named mutex. m->ReleaseMutex(); }
// This example shows how a named mutex is used to signal between // processes or threads. // Run this program from two (or more) command windows. Each process // creates a Mutex object that represents the named mutex "MyMutex". // The named mutex is a system object whose lifetime is bounded by the // lifetimes of the Mutex objects that represent it. The named mutex // is created when the first process creates its local Mutex; in this // example, the named mutex is owned by the first process. The named // mutex is destroyed when all the Mutex objects that represent it // have been released. // The second process (and any subsequent process) waits for earlier // processes to release the named mutex. import System.*; import System.Threading.*; import System.Threading.Thread; public class Test { public static void main(String[] args) { // Set this variable to false if you do not want to request // initial ownership of the named mutex. boolean requestInitialOwnership = true; boolean mutexWasCreated = false; // Request initial ownership of the named mutex by passing // true for the first parameter. Only one system object named // "MyMutex" can exist; the local Mutex object represents // this system object. If "MyMutex" is created by this call, // then mutexWasCreated contains true; otherwise, it contains // false. Mutex m = new Mutex(requestInitialOwnership, "MyMutex", mutexWasCreated); // This thread owns the mutex only if it both requested // initial ownership and created the named mutex. Otherwise , // it can request the named mutex by calling WaitOne. if (!((requestInitialOwnership && mutexWasCreated))) { Console.WriteLine("Waiting for the named mutex."); m.WaitOne(); } // Once the process has gained control of the named mutex, // hold onto it until the user presses ENTER. Console.WriteLine(("This process owns the named mutex. " + "Press ENTER to release the mutex and exit.")); Console.ReadLine(); // Call ReleaseMutex to allow other threads to gain control // of the named mutex. If you keep a reference to the local // Mutex, you can call WaitOne to request control of the // named mutex. m.ReleaseMutex(); } //main } //Test


Windows 98, Windows 2000 SP4, Windows Millennium Edition, Windows Server 2003, Windows XP Media Center Edition, Windows XP Professional x64 Edition, Windows XP SP2, Windows XP Starter Edition
開発プラットフォームの中には、.NET Framework によってサポートされていないバージョンがあります。サポートされているバージョンについては、「システム要件」を参照してください。


Mutex コンストラクタ (Boolean, String)
アセンブリ: mscorlib (mscorlib.dll 内)



name が null 参照 (Visual Basic では Nothing) ではなく initiallyOwned が true の場合、呼び出し元スレッドは、この呼び出しの結果として名前付きシステム ミューテックスが作成された場合にのみミューテックスを所有します。名前付きシステム ミューテックスが作成されたかどうかを確認するしくみはないため、このコンストラクタ オーバーロードを呼び出すときは initiallyOwned を false に設定することをお勧めします。初期所有権があるかどうかを調べる必要がある場合は、Mutex(Boolean,String,Boolean) コンストラクタを使用できます。
このコンストラクタは、名前付きシステム ミューテックスを表す Mutex オブジェクトを初期化します。同じ名前付きシステム ミューテックスを表す複数の Mutex オブジェクトを作成できます。
名前付きミューテックスがアクセス制御セキュリティで既に作成されていて、呼び出し元に MutexRights.FullControl がない場合は、例外がスローされます。スレッドの動作を同期するために必要な権限でのみ既存の名前付きミューテックスを開く方法については、OpenExisting メソッドに関するトピックを参照してください。
name に null 参照 (Visual Basic では Nothing) または空の文字列を指定すると、Mutex(Boolean) コンストラクタを呼び出した場合と同様に、ローカル ミューテックスが作成されます。この場合、createdNew は常に true です。

' This example shows how a named mutex is used to signal between ' processes or threads. ' Run this program from two (or more) command windows. Each process ' creates a Mutex object that represents the named mutex "MyMutex". ' The named mutex is a system object whose lifetime is bounded by the ' lifetimes of the Mutex objects that represent it. The named mutex ' is created when the first process creates its local Mutex; in this ' example, the named mutex is owned by the first process. The named ' mutex is destroyed when all the Mutex objects that represent it ' have been released. ' The constructor overload shown here cannot tell the calling thread ' whether initial ownership of the named mutex was granted. Therefore , ' do not request initial ownership unless you are certain that the ' thread will create the named mutex. Imports System Imports System.Threading Public Class Test <MTAThread> _ Public Shared Sub Main() ' Create the named mutex. Only one system object named ' "MyMutex" can exist; the local Mutex object represents ' this system object, regardless of which process or thread ' caused "MyMutex" to be created. Dim m As New Mutex(False, "MyMutex") ' Try to gain control of the named mutex. If the mutex is ' controlled by another thread, wait for it to be released. Console.WriteLine("Waiting for the Mutex.") m.WaitOne() ' Keep control of the mutex until the user presses ' ENTER. Console.WriteLine("This application owns the mutex. " _ & "Press ENTER to release the mutex and exit.") Console.ReadLine() m.ReleaseMutex() End Sub 'Main End Class 'Test
// This example shows how a named mutex is used to signal between // processes or threads. // Run this program from two (or more) command windows. Each process // creates a Mutex object that represents the named mutex "MyMutex". // The named mutex is a system object whose lifetime is bounded by the // lifetimes of the Mutex objects that represent it. The named mutex // is created when the first process creates its local Mutex; in this // example, the named mutex is owned by the first process. The named // mutex is destroyed when all the Mutex objects that represent it // have been released. // The constructor overload shown here cannot tell the calling thread // whether initial ownership of the named mutex was granted. Therefore , // do not request initial ownership unless you are certain that the // thread will create the named mutex. using System; using System.Threading; public class Test { public static void Main() { // Create the named mutex. Only one system object named // "MyMutex" can exist; the local Mutex object represents // this system object, regardless of which process or thread // caused "MyMutex" to be created. Mutex m = new Mutex(false, "MyMutex"); // Try to gain control of the named mutex. If the mutex is // controlled by another thread, wait for it to be released. Console.WriteLine("Waiting for the Mutex."); m.WaitOne(); // Keep control of the mutex until the user presses // ENTER. Console.WriteLine("This application owns the mutex. " + "Press ENTER to release the mutex and exit."); Console.ReadLine(); m.ReleaseMutex(); } }
// This example shows how a named mutex is used to signal between // processes or threads. // Run this program from two (or more) command windows. Each process // creates a Mutex object that represents the named mutex "MyMutex". // The named mutex is a system object whose lifetime is bounded by the // lifetimes of the Mutex objects that represent it. The named mutex // is created when the first process creates its local Mutex; in this // example, the named mutex is owned by the first process. The named // mutex is destroyed when all the Mutex objects that represent it // have been released. // The constructor overload shown here cannot tell the calling thread // whether initial ownership of the named mutex was granted. Therefore , // do not request initial ownership unless you are certain that the // thread will create the named mutex. using namespace System; using namespace System::Threading; int main() { // Create the named mutex. Only one system object named // "MyMutex" can exist; the local Mutex object represents // this system object, regardless of which process or thread // caused "MyMutex" to be created. Mutex^ m = gcnew Mutex( false,"MyMutex" ); // Try to gain control of the named mutex. If the mutex is // controlled by another thread, wait for it to be released. Console::WriteLine( "Waiting for the Mutex." ); m->WaitOne(); // Keep control of the mutex until the user presses // ENTER. Console::WriteLine( "This application owns the mutex. " "Press ENTER to release the mutex and exit." ); Console::ReadLine(); m->ReleaseMutex(); }
// This example shows how a named mutex is used to signal between // processes or threads. // Run this program from two (or more) command windows. Each process // creates a Mutex object that represents the named mutex "MyMutex". // The named mutex is a system object whose lifetime is bounded by the // lifetimes of the Mutex objects that represent it. The named mutex // is created when the first process creates its local Mutex; in this // example, the named mutex is owned by the first process. The named // mutex is destroyed when all the Mutex objects that represent it // have been released. // The constructor overload shown here cannot tell the calling thread // whether initial ownership of the named mutex was granted. Therefore , // do not request initial ownership unless you are certain that the // thread will create the named mutex. import System.*; import System.Threading.*; import System.Threading.Thread; public class Test { public static void main(String[] args) { // Create the named mutex. Only one system object named // "MyMutex" can exist; the local Mutex object represents // this system object, regardless of which process or thread // caused "MyMutex" to be created. Mutex m = new Mutex(false, "MyMutex"); // Try to gain control of the named mutex. If the mutex is // controlled by another thread, wait for it to be released. Console.WriteLine("Waiting for the Mutex."); m.WaitOne(); // Keep control of the mutex until the user presses // ENTER. Console.WriteLine(("This application owns the mutex. " + "Press ENTER to release the mutex and exit.")); Console.ReadLine(); m.ReleaseMutex(); } //main } //Test


Windows 98, Windows 2000 SP4, Windows Millennium Edition, Windows Server 2003, Windows XP Media Center Edition, Windows XP Professional x64 Edition, Windows XP SP2, Windows XP Starter Edition
開発プラットフォームの中には、.NET Framework によってサポートされていないバージョンがあります。サポートされているバージョンについては、「システム要件」を参照してください。


Mutex コンストラクタ

名前 | 説明 |
---|---|
Mutex () | Mutex クラスの新しいインスタンスを既定のプロパティを使用して初期化します。 .NET Compact Framework によってサポートされています。 |
Mutex (Boolean) | 呼び出し元のスレッドにミューテックスの初期所有権があるかどうかを示す Boolean 型の値を使用して、Mutex クラスの新しいインスタンスを初期化します。 .NET Compact Framework によってサポートされています。 |
Mutex (Boolean, String) | 呼び出し元のスレッドにミューテックスの初期所有権があるかどうかを示す Boolean 型の値と、ミューテックスの名前を表す文字列を使用して、Mutex クラスの新しいインスタンスを初期化します。 |
Mutex (Boolean, String, Boolean) | Boolean 型の値を使用して、Mutex クラスの新しいインスタンスを初期化します。この Boolean 型の値は、呼び出し元のスレッドにミューテックスの初期所有権があるかどうか、ミューテックスの名前を表す文字列、およびメソッドが返されるときにミューテックスの初期所有権が呼び出し元のスレッドに付与されたかどうかを示す Boolean 値を示します。 |
Mutex (Boolean, String, Boolean, MutexSecurity) | Boolean 型の値を使用して、Mutex クラスの新しいインスタンスを初期化します。この Boolean 型の値は、呼び出し元のスレッドにミューテックスの初期所有権があるかどうか、ミューテックスの名前を表す文字列、メソッドが返されるときにミューテックスの初期所有権が呼び出し元のスレッドに付与されたかどうかを示す Boolean 変数、および名前付きミューテックスに適用するアクセス制御セキュリティを示します。 |

Mutex プロパティ

名前 | 説明 | |
---|---|---|
![]() | Handle | ネイティブ オペレーティング システム ハンドルを取得または設定します。 ( WaitHandle から継承されます。) |
![]() | SafeWaitHandle | ネイティブ オペレーティング システム ハンドルを取得または設定します。 ( WaitHandle から継承されます。) |

Mutex メソッド


Mutex メンバ
Mutex データ型で公開されるメンバを以下の表に示します。


名前 | 説明 | |
---|---|---|
![]() | Handle | ネイティブ オペレーティング システム ハンドルを取得または設定します。(WaitHandle から継承されます。) |
![]() | SafeWaitHandle | ネイティブ オペレーティング システム ハンドルを取得または設定します。(WaitHandle から継承されます。) |


ミューテックス
ミューテックス (英: mutex) とは、コンピュータプログラミングにおける技術用語。クリティカルセクションでアトミック性を確保するための排他制御や同期機構の一種である。「mutex」という語は「mutual exclusion」 (相互排他、排他制御) の省略形である。ここでは、狭義の排他制御について述べる。
概要
セマフォをクリティカルセクションの排他制御に用いる時、セマフォでは(初期値が1でなければ)複数のタスクがクリティカルセクションに入ることを許可するのに対し、ミューテックスでは同時に一つのタスクのみがクリティカルセクションに入ることを許可する(ここで言うタスクとは、スレッドまたはプロセスを指す)。挙動はセマフォ変数の初期値を1にする事と等価。このようなタスク優先度とリンクしないミューテックスを、バイナリセマフォと呼ぶ場合もある。
狭義には、ミューテックスの場合にそれをロック(P操作)したタスクのみがアンロック(V操作)できるのに対して、セマフォではその様な制約はない。また、ミューテックスには、優先度逆転を防止するための優先度継承 (Priority Inheritance) 機能や、デッドロックを防止するための優先度上限プロトコル (Priority Ceiling Protocol) 機能などが拡張されていることがある。
一般的には異なるタスク間で排他制御を行いたい時に使用するが、マルチタスク環境ではプロセスの多重起動を防止する用途にも使える。
ミューテックスの起源はディジタル・イクイップメント・コーポレーションにおける、機材の使用管理が由来である。使用可能な機材の上には小さな旗が置かれ、その旗を手にいれた者がその機材の使用権利を獲得する[1]。この排他制御からヒントを得たVMS開発チームはVMSの排他制御にミューテックスを実現した。そしてその技術はデヴィッド・カトラーを筆頭としたVMS開発チームと共にMicrosoft Windows NTにも移された(著:戦うプログラマー[要文献特定詳細情報]より)。
POSIXスレッド (Pthreads) のミューテックスは、VMSやWin32と違い、自らP操作したミューテックスをさらにP操作するとデッドロックを起こす(そして誰もロックを解除できなくなる)。そのため若干取り扱いは不便である。再帰ロックを許可する場合は、ミューテックスの初期化時にPTHREAD_MUTEX_RECURSIVE
を設定した属性を使用する必要がある。
ミューテックスを実現する方法は様々あり、大きくハードウェアによる方式とソフトウェアによる方式に分けられる。ソフトウェアによる方式にも、様々なアルゴリズムが提案されている。詳しくは、排他制御の実施を参照。
ミューテックスの使用
ミューテックス機構を使用するには、プログラムでミューテックスオブジェクトを作成する必要がある。ミューテックスオブジェクトはシグナルおよび非シグナルの二つの状態を持ち、それぞれミューテックスオブジェクトが所有可能および所有不可能である事を表す。
クリティカルセクションへの進入
クリティカルセクションに入るにはミューテックスオブジェクトの所有を行う。所有というのはインスタンスの作成という意味ではなく、クリティカルセクションへの進入権を得るという事である。この時、ミューテックスオブジェクトの状態によってクリティカルセクションに入れるかどうかが異なる。
- シグナル状態
- すぐにクリティカルセクションに入る事ができ、処理を続行できる。この時、ミューテックスオブジェクトはシグナル状態から非シグナル状態になり、これによって後続のタスクが同時にクリティカルセクションに入る事を防ぐ。
- 非シグナル状態
- クリティカルセクションに入る事はできず、通常はシグナル状態になるまで(ミューテックスオブジェクトが解放されるまで)タスクは待機状態になる。実装によってはタイムアウトを指定する事ができ、指定した期間内にミューテックスオブジェクトが解放されなければ所有は失敗し、タスクに処理が戻る。この時、タスクは所有が失敗した事を感知し、処理を中断するべきである。
クリティカルセクションからの離脱
クリティカルセクションから抜ける時はミューテックスオブジェクトを解放する。解放されたミューテックスオブジェクトは非シグナル状態からシグナル状態に戻り、これによって後続のタスクはミューテックスオブジェクトを所有する事が可能になる。
環境ごとの使用法
POSIX
プロセス間の場合
Pthreadsのミューテックスオブジェクトを初期化する際に使用する属性pthread_mutexattr_t
に対して、pthread_mutexattr_setpshared()
関数にてPTHREAD_PROCESS_SHARED
を指定する。ただしサポートされない環境もある。
プロセス内(スレッド間)の場合
Pthreadsのミューテックスオブジェクトpthread_mutex_t
を使う。
Windows
プロセス間の場合
プロセス間の排他制御には、以下の方法がある。
- Mutex - ミューテックスオブジェクトを使う。初期化には
CreateMutex()
Win32 API関数を使う。 - Metered Section - Critical Sectionの拡張であり、
CreateMeteredSection()
関数の実装例がMSDNに記載されている。Mutexより高速であるとされている[2]。[1][リンク切れ][2][リンク切れ]
プロセス内(スレッド間)の場合
プロセス間でミューテックスを共有する必要がない場合は、以下の方法がある。
- Critical Section - クリティカルセクションオブジェクトを使う。初期化には
InitializeCriticalSection()
Win32 API関数を使う。Mutexより高速である。 - Mutex - 無名のミューテックスオブジェクトを使う。
MFCにはC++のコンストラクタ/デストラクタによるRAII機構を利用した、Win32同期オブジェクトのラッパークラスCMutex
[3]やCCriticalSection
[4]が用意されている(実際にはCSingleLock
と組み合わせて使用することが多い[5])。
C++
PthreadsやWin32 APIを直接使用するか、あるいは以下に述べるようなポータブルなライブラリを使用する。
プロセス間の場合
Boost C++ライブラリのboost::interprocess::interprocess_mutex
などを使う。内部的には共有メモリやメモリマップトファイルを使って実装されることもある[6]。Windows実装の場合はWin32ミューテックスを使う実験的コードも存在する[7]。
プロセス内(スレッド間)の場合
Boost C++ライブラリのboost::mutex
や、C++11以降で標準化されたstd::mutex
を使う。再帰ロックを許可する場合は、boost::recursive_mutex
やstd::recursive_mutex
を使う。通常はlock_guard
やunique_lock
といったロック管理クラスと組み合わせて使用することが多い[8][9]。
.NET
プロセス間の場合
System.Threading.Mutex
クラスを使う。
プロセス内(スレッド間)の場合
System.Threading.Monitor
クラスが用意されているが、このクラスを使用した言語組み込みの同期機能も用意されている。例えばC#では lock
ステートメント、Visual Basic .NETでは SyncLock
ステートメントで、クリティカルセクションを任意のロックオブジェクトにより相互排他ロックすることが可能である。ただし、this
オブジェクトやSystem.Type
インスタンスなど、ロックに使用してはいけないとされているオブジェクトもある[10]。また、メソッド全体を包含する場合は、[MethodImplAttribute(MethodImplOptions.Synchronized)]
属性[11]を適用することができる(Javaのsynchronizedメソッドに相当)。ただしC# 5.0/VB.NET 11で追加されたawait/Await演算子を含むコードブロックをlock/SyncLockでロックすることはできず、System.Threading.SemaphoreSlim
クラスなどを使用する必要がある。
C++/CLI向けにはRAIIを応用したmsclr::lock
クラスが用意されている[12]。
Java
Javaにはミューテックスクラスが存在せず、パーミッション数1で初期化したjava.util.concurrent.Semaphore
クラスで代用する。また、スレッドの同期機構が言語仕様に組み込んであり、synchronized
ブロックにて任意のオブジェクトをロックオブジェクト(ミューテックス)として使用できる。synchronized
メソッドではthis
オブジェクトもしくはjava.lang.Class
がロックに使われる。プロセス間で使用可能なミューテックスは直接サポートされておらず、ファイルロック (java.nio.channels.FileChannel
, java.nio.channels.FileLock
) を利用する必要がある。
μITRON仕様
3.0仕様以前には、ミューテックスは存在しない。広義のミューテックスはセマフォで代用することは可能であるが、優先度逆転を防げない。 しかしながら、3.0仕様準拠OSでも、実装独自に優先度逆転を防止できるミューテックスが存在する可能性はある。
4.0仕様以降では、優先度上限および優先度継承をサポートするミューテックスオブジェクトが追加された。しかし、スタンダードプロファイルには含まれておらず、実質オプション扱いである。
脚注
- ^ VAX & VMS ものがたり - 20年目を迎えた VAX&VMS -
- ^ 短時間でできる汎用の同期オブジェクト | MSDN, Internet Archive
- ^ CMutex Class | Microsoft Learn
- ^ CCriticalSection Class | Microsoft Learn
- ^ Multithreading: How to Use the MFC Synchronization Classes | Microsoft Learn
- ^ Synchronization mechanisms - 1.81.0
- ^ interprocess/include/boost/interprocess/sync/interprocess_mutex.hpp at boost-1.81.0 · boostorg/interprocess | GitHub
- ^ mutex - cpprefjp C++日本語リファレンス
- ^ recursive_mutex - cpprefjp C++日本語リファレンス
- ^ lock ステートメント - C# リファレンス | Microsoft Docs
- ^ マルチスレッド処理のためのデータの同期 | Microsoft Docs
- ^ lock クラス | Microsoft Docs
関連項目
- mutexのページへのリンク