Mutex Kelas
Definisi
Penting
Beberapa informasi terkait produk prarilis yang dapat diubah secara signifikan sebelum dirilis. Microsoft tidak memberikan jaminan, tersirat maupun tersurat, sehubungan dengan informasi yang diberikan di sini.
Primitif sinkronisasi yang juga dapat digunakan untuk sinkronisasi antarprosek.
public ref class Mutex sealed : System::Threading::WaitHandle
public sealed class Mutex : System.Threading.WaitHandle
[System.Runtime.InteropServices.ComVisible(true)]
public sealed class Mutex : System.Threading.WaitHandle
type Mutex = class
inherit WaitHandle
[<System.Runtime.InteropServices.ComVisible(true)>]
type Mutex = class
inherit WaitHandle
Public NotInheritable Class Mutex
Inherits WaitHandle
- Warisan
- Warisan
- Atribut
Contoh
Contoh ini menunjukkan bagaimana objek lokal Mutex digunakan untuk menyinkronkan akses ke sumber daya yang dilindungi. Karena setiap utas panggilan diblokir sampai memperoleh kepemilikan mutex, ia harus memanggil ReleaseMutex metode untuk melepaskan kepemilikan mutex.
using System;
using System.Threading;
class Example
{
// 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 newThread = new Thread(new ThreadStart(ThreadProc));
newThread.Name = String.Format("Thread{0}", i + 1);
newThread.Start();
}
// The main thread exits, but the application continues to
// run until all foreground threads have exited.
}
private static void ThreadProc()
{
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.
Console.WriteLine("{0} is requesting the mutex",
Thread.CurrentThread.Name);
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",
Thread.CurrentThread.Name);
// Release the Mutex.
mut.ReleaseMutex();
Console.WriteLine("{0} has released the mutex",
Thread.CurrentThread.Name);
}
}
// The example displays output like the following:
// Thread1 is requesting the mutex
// Thread2 is requesting the mutex
// Thread1 has entered the protected area
// Thread3 is requesting the mutex
// Thread1 is leaving the protected area
// Thread1 has released the mutex
// Thread3 has entered the protected area
// Thread3 is leaving the protected area
// Thread3 has released the mutex
// Thread2 has entered the protected area
// Thread2 is leaving the protected area
// Thread2 has released the mutex
Imports System.Threading
Module Example
' Create a new Mutex. The creating thread does not own the mutex.
Private mut As New Mutex()
Private Const numIterations As Integer = 1
Private Const numThreads As Integer = 3
Public Sub Main()
' Create the threads that will use the protected resource.
For i As Integer = 0 To numThreads - 1
Dim newThread As New Thread(AddressOf ThreadProc)
newThread.Name = String.Format("Thread{0}", i + 1)
newThread.Start()
Next
' The main thread exits, but the application continues to
' run until all foreground threads have exited.
End Sub
Private Sub ThreadProc()
For i As Integer = 0 To numIterations - 1
UseResource()
Next
End Sub
' This method represents a resource that must be synchronized
' so that only one thread at a time can enter.
Private Sub UseResource()
' Wait until it is safe to enter.
Console.WriteLine("{0} is requesting the mutex",
Thread.CurrentThread.Name)
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",
Thread.CurrentThread.Name)
' Release the Mutex.
mut.ReleaseMutex()
Console.WriteLine("{0} has released the mutex",
Thread.CurrentThread.Name)
End Sub
End Module
' The example displays output like the following:
' Thread1 is requesting the mutex
' Thread2 is requesting the mutex
' Thread1 has entered the protected area
' Thread3 is requesting the mutex
' Thread1 is leaving the protected area
' Thread1 has released the mutex
' Thread3 has entered the protected area
' Thread3 is leaving the protected area
' Thread3 has released the mutex
' Thread2 has entered the protected area
' Thread2 is leaving the protected area
' Thread2 has released the mutex
Dalam contoh berikut, setiap utas WaitOne(Int32) memanggil metode untuk memperoleh mutex. Jika interval waktu habis berlalu, metode mengembalikan , dan utas false
tidak memperoleh mutex atau mendapatkan akses ke sumber daya yang dilindungi mutex. Metode ReleaseMutex ini hanya dipanggil oleh utas yang memperoleh mutex.
using System;
using System.Threading;
class Example
{
// 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()
{
Example ex = new Example();
ex.StartThreads();
}
private void StartThreads()
{
// Create the threads that will use the protected resource.
for(int i = 0; i < numThreads; i++)
{
Thread newThread = new Thread(new ThreadStart(ThreadProc));
newThread.Name = String.Format("Thread{0}", i + 1);
newThread.Start();
}
// The main thread returns to Main and exits, but the application continues to
// run until all foreground threads have exited.
}
private static void ThreadProc()
{
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, and do not enter if the request times out.
Console.WriteLine("{0} is requesting the mutex", Thread.CurrentThread.Name);
if (mut.WaitOne(1000)) {
Console.WriteLine("{0} has entered the protected area",
Thread.CurrentThread.Name);
// Place code to access non-reentrant resources here.
// Simulate some work.
Thread.Sleep(5000);
Console.WriteLine("{0} is leaving the protected area",
Thread.CurrentThread.Name);
// Release the Mutex.
mut.ReleaseMutex();
Console.WriteLine("{0} has released the mutex",
Thread.CurrentThread.Name);
}
else {
Console.WriteLine("{0} will not acquire the mutex",
Thread.CurrentThread.Name);
}
}
~Example()
{
mut.Dispose();
}
}
// The example displays output like the following:
// Thread1 is requesting the mutex
// Thread1 has entered the protected area
// Thread2 is requesting the mutex
// Thread3 is requesting the mutex
// Thread2 will not acquire the mutex
// Thread3 will not acquire the mutex
// Thread1 is leaving the protected area
// Thread1 has released the mutex
Imports System.Threading
Class Example
' Create a new Mutex. The creating thread does not own the mutex.
Private mut As New Mutex()
Private Const numIterations As Integer = 1
Private Const numThreads As Integer = 3
Public Shared Sub Main()
Dim ex As New Example()
ex.StartThreads()
End Sub
Private Sub StartThreads()
' Create the threads that will use the protected resource.
For i As Integer = 0 To numThreads - 1
Dim newThread As New Thread(AddressOf ThreadProc)
newThread.Name = String.Format("Thread{0}", i + 1)
newThread.Start()
Next
' The main thread returns to Main and exits, but the application continues to
' run until all foreground threads have exited.
End Sub
Private Sub ThreadProc()
For i As Integer = 0 To numIterations - 1
UseResource()
Next
End Sub
' This method represents a resource that must be synchronized
' so that only one thread at a time can enter.
Private Sub UseResource()
' Wait until it is safe to enter.
Console.WriteLine("{0} is requesting the mutex",
Thread.CurrentThread.Name)
If mut.WaitOne(1000) Then
Console.WriteLine("{0} has entered the protected area",
Thread.CurrentThread.Name)
' Place code to access non-reentrant resources here.
' Simulate some work.
Thread.Sleep(5000)
Console.WriteLine("{0} is leaving the protected area",
Thread.CurrentThread.Name)
' Release the Mutex.
mut.ReleaseMutex()
Console.WriteLine("{0} has released the mutex",
Thread.CurrentThread.Name)
Else
Console.WriteLine("{0} will not acquire the mutex",
Thread.CurrentThread.Name)
End If
End Sub
Protected Overrides Sub Finalize()
mut.Dispose()
End Sub
End Class
' The example displays output like the following:
' Thread1 is requesting the mutex
' Thread1 has entered the protected area
' Thread2 is requesting the mutex
' Thread3 is requesting the mutex
' Thread2 will not acquire the mutex
' Thread3 will not acquire the mutex
' Thread1 is leaving the protected area
' Thread1 has released the mutex
Keterangan
Ketika dua utas atau lebih perlu mengakses sumber daya bersama pada saat yang sama, sistem memerlukan mekanisme sinkronisasi untuk memastikan bahwa hanya satu utas pada satu waktu yang menggunakan sumber daya. Mutex adalah primitif sinkronisasi yang memberikan akses eksklusif ke sumber daya bersama hanya untuk satu utas. Jika utas memperoleh mutex, utas kedua yang ingin memperoleh mutex tersebut ditangguhkan hingga utas pertama melepaskan mutex.
Penting
Jenis ini mengimplementasikan IDisposable antarmuka. Ketika Anda telah selesai menggunakan jenis , Anda harus membuangnya baik secara langsung atau tidak langsung. Untuk membuang jenis secara langsung, panggil metodenya Dispose dalam try
/catch
blok. Untuk membuangnya secara tidak langsung, gunakan konstruksi bahasa seperti using
(di C#) atau Using
(di Visual Basic). Untuk informasi selengkapnya, lihat bagian "Menggunakan Objek yang Mengimplementasikan IDisposable" di IDisposable topik antarmuka.
Anda dapat menggunakan WaitHandle.WaitOne metode untuk meminta kepemilikan mutex. Alur panggilan memblokir hingga salah satu hal berikut ini terjadi:
Mutex disinyalkan untuk menunjukkan bahwa itu tidak dimiliki. Ketika ini terjadi, WaitOne metode mengembalikan , dan utas
true
panggilan mengasumsikan kepemilikan mutex dan mengakses sumber daya yang dilindungi oleh mutex. Setelah selesai mengakses sumber daya, utas harus memanggil ReleaseMutex metode untuk merilis kepemilikan mutex. Contoh pertama di bagian Contoh mengilustrasikan pola ini.Interval waktu habis yang ditentukan dalam panggilan ke WaitOne metode yang memiliki
millisecondsTimeout
parameter atautimeout
telah berlalu. Ketika ini terjadi, WaitOne metode mengembalikan , dan utasfalse
panggilan tidak membuat upaya lebih lanjut untuk memperoleh kepemilikan mutex. Dalam hal ini, Anda harus menyusun kode Anda sehingga akses ke sumber daya yang dilindungi oleh mutex ditolak ke utas panggilan. Karena utas tidak pernah memperoleh kepemilikan mutex, utas tidak boleh memanggil ReleaseMutex metode . Contoh kedua di bagian Contoh mengilustrasikan pola ini.
Kelas memberlakukan Mutex identitas utas, sehingga mutex hanya dapat dirilis oleh utas yang memperolehnya. Sebaliknya, Semaphore kelas tidak memberlakukan identitas utas. Mutex juga dapat diteruskan di seluruh batas domain aplikasi.
Utas yang memiliki mutex dapat meminta mutex yang sama dalam panggilan berulang tanpa WaitOne memblokir eksekusinya. Namun, utas harus memanggil ReleaseMutex metode dengan jumlah yang sama untuk merilis kepemilikan mutex.
Mutex Karena kelas mewarisi dari WaitHandle, Anda juga dapat memanggil statis WaitHandle.WaitAll dan WaitHandle.WaitAny metode untuk menyinkronkan akses ke sumber daya yang dilindungi.
Jika utas berakhir saat memiliki mutex, muteks dikatakan ditinggalkan. Status mutex diatur ke sinyal, dan utas tunggu berikutnya mendapatkan kepemilikan. Mulai versi 2.0 dari .NET Framework, AbandonedMutexException dilemparkan ke utas berikutnya yang memperoleh mutex yang ditinggalkan. Sebelum versi 2.0 dari .NET Framework, tidak ada pengecualian yang dilemparkan.
Perhatian
Mutex yang ditinggalkan sering menunjukkan kesalahan serius dalam kode. Ketika utas keluar tanpa melepaskan mutex, struktur data yang dilindungi oleh mutex mungkin tidak dalam keadaan konsisten. Utas berikutnya untuk meminta kepemilikan mutex dapat menangani pengecualian ini dan melanjutkan, jika integritas struktur data dapat diverifikasi.
Dalam kasus mutex di seluruh-sistem, mutex yang ditinggalkan mungkin menunjukkan bahwa aplikasi telah dihentikan tiba-tiba (misalnya, dengan menggunakan Windows Task Manager).
Mutex terdiri dari dua jenis: mutex lokal, yang tidak bernama, dan mutex sistem bernama. Mutex lokal hanya ada dalam proses Anda. Ini dapat digunakan oleh utas apa pun dalam proses Anda yang memiliki referensi ke Mutex objek yang mewakili mutex. Setiap objek yang tidak disebutkan Mutex namanya mewakili mutex lokal terpisah.
Mutex sistem bernama terlihat di seluruh sistem operasi, dan dapat digunakan untuk menyinkronkan aktivitas proses. Anda dapat membuat Mutex objek yang mewakili mutex sistem bernama dengan menggunakan konstruktor yang menerima nama. Objek sistem operasi dapat dibuat pada saat yang sama, atau dapat ada sebelum pembuatan Mutex objek. Anda dapat membuat beberapa objek Mutex yang mewakili mutex sistem bernama yang sama, dan Anda dapat menggunakan metode OpenExisting untuk membuka mutex sistem bernama yang ada.
Catatan
Pada server yang menjalankan Layanan Terminal, mutex sistem bernama dapat memiliki dua tingkat visibilitas. Jika namanya dimulai dengan awalan Global\
, mutex terlihat di semua sesi server terminal. Jika namanya dimulai dengan awalan Local\
, mutex hanya terlihat di sesi server terminal tempatnya dibuat. Dalam hal ini, mutex terpisah dengan nama yang sama dapat ada di masing-masing sesi server terminal lainnya di server. Jika Anda tidak menentukan awalan saat membuat mutex bernama, dibutuhkan awalan Local\
. Dalam sesi server terminal, dua mutex yang namanya hanya berbeda dengan awalannya adalah mutex terpisah, dan keduanya terlihat oleh semua proses dalam sesi server terminal. Artinya, nama Global\
awalan dan Local\
menjelaskan cakupan nama mutex relatif terhadap sesi server terminal, tidak relatif terhadap proses.
Perhatian
Secara default, mutex bernama tidak dibatasi untuk pengguna yang membuatnya. Pengguna lain mungkin dapat membuka dan menggunakan mutex, termasuk mengganggu mutex dengan memasukkan mutex dan tidak keluar darinya. Pada sistem operasi seperti Unix, sistem file digunakan dalam implementasi mutex bernama, dan pengguna lain mungkin dapat mengganggu muteks bernama dengan cara yang lebih signifikan. Di Windows, untuk membatasi akses ke pengguna tertentu, Anda dapat menggunakan konstruktor kelebihan beban atau MutexAcl dan meneruskan MutexSecurity saat membuat mutex bernama. Pada sistem operasi seperti Unix, saat ini tidak ada cara untuk membatasi akses ke mutex bernama. Hindari menggunakan mutex bernama tanpa pembatasan akses pada sistem yang mungkin memiliki pengguna yang tidak tepercaya yang menjalankan kode.
Garis miring terbelakang (\) adalah karakter yang dicadangkan dalam nama mutex. Jangan gunakan garis miring terbalik (\) dalam nama mutex kecuali seperti yang ditentukan dalam catatan tentang menggunakan mutex di sesi server terminal. Jika tidak, DirectoryNotFoundException mungkin dilemparkan, meskipun nama mutex mewakili file yang ada.
Konstruktor
Mutex() |
Menginisialisasi instans Mutex baru kelas dengan properti default. |
Mutex(Boolean) |
Menginisialisasi instans Mutex baru kelas dengan nilai Boolean yang menunjukkan apakah utas panggilan harus memiliki kepemilikan awal mutex. |
Mutex(Boolean, String) |
Menginisialisasi instans Mutex baru kelas dengan nilai Boolean yang menunjukkan apakah utas panggilan harus memiliki kepemilikan awal mutex, dan string yang merupakan nama mutex. |
Mutex(Boolean, String, Boolean) |
Menginisialisasi instans Mutex baru kelas dengan nilai Boolean yang menunjukkan apakah utas panggilan harus memiliki kepemilikan awal mutex, string yang merupakan nama muteks, dan nilai Boolean yang, ketika metode kembali, menunjukkan apakah utas panggilan diberikan kepemilikan awal mutex. |
Mutex(Boolean, String, Boolean, MutexSecurity) |
Menginisialisasi instans Mutex baru kelas dengan nilai Boolean yang menunjukkan apakah utas panggilan harus memiliki kepemilikan awal mutex, string yang merupakan nama muteks, variabel Boolean yang, ketika metode kembali, menunjukkan apakah utas panggilan diberikan kepemilikan awal mutex, dan keamanan kontrol akses yang akan diterapkan ke mutex bernama. |
Bidang
WaitTimeout |
Menunjukkan bahwa operasi kehabisan WaitAny(WaitHandle[], Int32, Boolean) waktu sebelum salah satu handel tunggu diberi sinyal. Bidang ini konstan. (Diperoleh dari WaitHandle) |
Properti
Handle |
Kedaluwarsa.
Kedaluwarsa.
Mendapatkan atau mengatur handel sistem operasi asli. (Diperoleh dari WaitHandle) |
SafeWaitHandle |
Mendapatkan atau mengatur handel sistem operasi asli. (Diperoleh dari WaitHandle) |
Metode
Close() |
Merilis semua sumber daya yang dipegang oleh saat ini WaitHandle. (Diperoleh dari WaitHandle) |
CreateObjRef(Type) |
Membuat objek yang berisi semua informasi relevan yang diperlukan untuk menghasilkan proksi yang digunakan untuk berkomunikasi dengan objek jarak jauh. (Diperoleh dari MarshalByRefObject) |
Dispose() |
Merilis semua sumber daya yang digunakan oleh instans WaitHandle kelas saat ini. (Diperoleh dari WaitHandle) |
Dispose(Boolean) |
Ketika ditimpa di kelas turunan, merilis sumber daya tidak terkelola yang digunakan oleh WaitHandle, dan secara opsional merilis sumber daya terkelola. (Diperoleh dari WaitHandle) |
Equals(Object) |
Menentukan apakah objek yang ditentukan sama dengan objek saat ini. (Diperoleh dari Object) |
GetAccessControl() |
MutexSecurity Mendapatkan objek yang mewakili keamanan kontrol akses untuk mutex bernama. |
GetHashCode() |
Berfungsi sebagai fungsi hash default. (Diperoleh dari Object) |
GetLifetimeService() |
Kedaluwarsa.
Mengambil objek layanan seumur hidup saat ini yang mengontrol kebijakan seumur hidup untuk instans ini. (Diperoleh dari MarshalByRefObject) |
GetType() |
Mendapatkan dari instans Type saat ini. (Diperoleh dari Object) |
InitializeLifetimeService() |
Kedaluwarsa.
Mendapatkan objek layanan seumur hidup untuk mengontrol kebijakan seumur hidup untuk instans ini. (Diperoleh dari MarshalByRefObject) |
MemberwiseClone() |
Membuat salinan dangkal dari saat ini Object. (Diperoleh dari Object) |
MemberwiseClone(Boolean) |
Membuat salinan dangkal objek saat ini MarshalByRefObject . (Diperoleh dari MarshalByRefObject) |
OpenExisting(String) |
Membuka mutex bernama yang ditentukan, jika sudah ada. |
OpenExisting(String, MutexRights) |
Membuka mutex bernama yang ditentukan, jika sudah ada, dengan akses keamanan yang diinginkan. |
ReleaseMutex() |
Merilis sekali Mutex . |
SetAccessControl(MutexSecurity) |
Mengatur keamanan kontrol akses untuk mutex sistem bernama. |
ToString() |
Mengembalikan string yang mewakili objek saat ini. (Diperoleh dari Object) |
TryOpenExisting(String, Mutex) |
Membuka mutex bernama yang ditentukan, jika sudah ada, dan mengembalikan nilai yang menunjukkan apakah operasi berhasil. |
TryOpenExisting(String, MutexRights, Mutex) |
Membuka mutex bernama yang ditentukan, jika sudah ada, dengan akses keamanan yang diinginkan, dan mengembalikan nilai yang menunjukkan apakah operasi berhasil. |
WaitOne() |
Memblokir utas saat ini hingga saat ini WaitHandle menerima sinyal. (Diperoleh dari WaitHandle) |
WaitOne(Int32) |
Memblokir utas saat ini hingga saat ini WaitHandle menerima sinyal, menggunakan bilangan bulat bertanda tangan 32-bit untuk menentukan interval waktu dalam milidetik. (Diperoleh dari WaitHandle) |
WaitOne(Int32, Boolean) |
Memblokir utas saat ini hingga saat ini WaitHandle menerima sinyal, menggunakan bilangan bulat bertanda tangan 32-bit untuk menentukan interval waktu dan menentukan apakah akan keluar dari domain sinkronisasi sebelum menunggu. (Diperoleh dari WaitHandle) |
WaitOne(TimeSpan) |
Memblokir utas saat ini hingga instans saat ini menerima sinyal, menggunakan TimeSpan untuk menentukan interval waktu. (Diperoleh dari WaitHandle) |
WaitOne(TimeSpan, Boolean) |
Memblokir utas saat ini hingga instans saat ini menerima sinyal, menggunakan TimeSpan untuk menentukan interval waktu dan menentukan apakah akan keluar dari domain sinkronisasi sebelum menunggu. (Diperoleh dari WaitHandle) |
Implementasi Antarmuka Eksplisit
IDisposable.Dispose() |
API ini mendukung infrastruktur produk dan tidak dimaksudkan untuk digunakan langsung dari kode Anda. Merilis semua sumber daya yang WaitHandledigunakan oleh . (Diperoleh dari WaitHandle) |
Metode Ekstensi
GetAccessControl(Mutex) |
Mengembalikan deskriptor keamanan untuk yang ditentukan |
SetAccessControl(Mutex, MutexSecurity) |
Mengatur deskriptor keamanan untuk mutex yang ditentukan. |
GetSafeWaitHandle(WaitHandle) |
Mendapatkan handel yang aman untuk handel tunggu sistem operasi asli. |
SetSafeWaitHandle(WaitHandle, SafeWaitHandle) |
Mengatur handel yang aman untuk handel tunggu sistem operasi asli. |
Berlaku untuk
Keamanan Thread
Jenis ini aman untuk utas.