Bagikan melalui


Mutex Kelas

Definisi

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 falsetidak 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 truepanggilan 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 atau timeout telah berlalu. Ketika ini terjadi, WaitOne metode mengembalikan , dan utas falsepanggilan 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 mutex.

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.

Lihat juga