Sự khác biệt giữa khóa và Mutex là gì?


129

Sự khác biệt giữa khóa và Mutex là gì? Tại sao chúng không thể được sử dụng thay thế cho nhau?

Câu trả lời:


146

Một khóa là cụ thể cho AppDomain, trong khi Mutex để hệ điều hành cho phép bạn thực hiện inter-process khóa và đồng bộ hóa (IPC).


95

locklà một từ khóa trình biên dịch, không phải là một lớp hoặc đối tượng thực tế. Đó là một trình bao bọc xung quanh chức năng của Monitorlớp và được thiết kế để làm việc Monitordễ dàng hơn với trường hợp thông thường.

Các Monitor(và các locktừ khóa) là, như Darin nói, hạn chế đến AppDomain. Chủ yếu bởi vì tham chiếu đến một địa chỉ bộ nhớ (ở dạng đối tượng được khởi tạo) là bắt buộc để quản lý "khóa" và duy trì danh tính củaMonitor

Mặt Mutexkhác, là một trình bao bọc .Net xung quanh cấu trúc hệ điều hành và có thể được sử dụng để đồng bộ hóa toàn hệ thống, sử dụng dữ liệu chuỗi (thay vì con trỏ tới dữ liệu) làm định danh. Hai mutex tham chiếu hai chuỗi trong hai địa chỉ bộ nhớ hoàn toàn khác nhau, nhưng có cùng dữ liệu , sẽ thực sự sử dụng cùng một mutex hệ điều hành.


54

A Mutexcó thể là cục bộ của một quá trình hoặc toàn hệ thống . MSDN :

Mutexes có hai loại: mutexes cục bộ, không được đặt tên và mutexes hệ thống được đặt tên. Một mutex cục bộ chỉ tồn tại trong quá trình của bạn.

Hơn nữa, người ta cũng cần đặc biệt cẩn thận - chi tiết trên cùng một trang - khi sử dụng một mutex toàn hệ thống trên một hệ thống với Terminal Services.

Một trong những khác biệt giữa MutexlockMutexsử dụng cấu trúc cấp kernel , do đó, đồng bộ hóa sẽ luôn yêu cầu ít nhất một chuyển đổi không gian kernel-kernel.

lock- đó thực sự là một lối tắt đến Monitorlớp , mặt khác cố gắng tránh phân bổ tài nguyên kernel và chuyển sang mã kernel (và do đó gọn hơn & nhanh hơn - nếu người ta phải tìm một cấu trúc WinAPI giống với nó, thì nó sẽ như vậy CriticalSection).

Sự khác biệt khác là những gì người khác chỉ ra: một cái tên Mutex có thể được sử dụng trên các quy trình.

Trừ khi một người có nhu cầu đặc biệt hoặc yêu cầu đồng bộ hóa qua các quy trình, tốt hơn hết là bạn nên bám vào lock(aka Monitor)

Có một số khác biệt "nhỏ" khác, như cách xử lý từ bỏ, v.v.

Điều tương tự cũng có thể nói về ReaderWriterLockReaderWriterLockSlimtrong 3.5, Semaphorevà mới SemaphoreSlimtrong .NET 4.0, v.v ... Đúng là các xxSlimlớp sau không thể được sử dụng như một nguyên hàm đồng bộ hóa toàn hệ thống, nhưng chúng không bao giờ có nghĩa - chúng chỉ "có nghĩa" để nhanh hơn và thân thiện hơn với tài nguyên.


25

Tôi sử dụng Mutex để kiểm tra xem tôi đã có bản sao của ứng dụng đang chạy trên cùng một máy chưa.

bool firstInstance;
Mutex mutex = new Mutex(false, @"Local\DASHBOARD_MAIN_APPLICATION", out firstInstance);

if (!firstInstance)
{
    //another copy of this application running 
}
else
{
    //run main application loop here.
}
// Refer to the mutex down here so garbage collection doesn't chuck it out.
GC.KeepAlive(mutex);

8

Rất nhiều điều đã được nói, nhưng để làm cho nó đơn giản, đây là của tôi.

khóa -> Sử dụng đơn giản, trình bao bọc trên màn hình, khóa trên các luồng trong AppDomain.

mutex chưa được đặt tên -> tương tự như khóa ngoại trừ phạm vi khóa là nhiều hơn và nó nằm trên AppDomain trong một quy trình.

Mutex được đặt tên -> phạm vi khóa thậm chí còn nhiều hơn mutex không tên và nó xuyên suốt quá trình trong một hệ điều hành.

Vì vậy, bây giờ các tùy chọn đã có, bạn cần chọn một trong những phù hợp nhất trong trường hợp của bạn.


Như tôi đã hiểu từ các câu trả lời và các ví dụ cho mutex ở đây msdn.microsoft.com/en-us/l Library / Lỗi : một mutex không tên hoạt động giống như một khóa. Tuy nhiên mutex.WaitOne (1000) cho chúng ta cơ hội hết thời gian khóa. Mặt khác, Monitor.Try Entry cũng cho chúng ta khả năng đó. Như đã đề cập, Mutex là một trình bao bọc. Vì vậy, tôi sẽ sử dụng khóa hoặc Màn hình thay vì một mutex không tên. Nhưng nếu có một khóa trên các quy trình được yêu cầu, một mutex có tên là cách để đi. Xin hãy sửa tôi nếu tôi sai.
Koray

6

Mutex là một quá trình chéo và sẽ có một ví dụ kinh điển về việc không chạy nhiều hơn một phiên bản của một ứng dụng.

Ví dụ thứ hai là bạn đang có một tệp và bạn không muốn có quá trình khác nhau để truy cập cùng một tệp, bạn có thể triển khai Mutex nhưng hãy nhớ một điều Mutex là một hệ điều hành rộng và không thể sử dụng giữa hai quy trình từ xa.

Khóa là một cách đơn giản nhất để bảo vệ phần mã của bạn và nó là tên miền cụ thể, bạn có thể thay thế khóa bằng Moniter nếu bạn muốn đồng bộ hóa được kiểm soát nhiều hơn.


1

Một số khác biệt nhỏ hơn không được đề cập trong các câu trả lời:

  1. Trong trường hợp sử dụng khóa, bạn có thể chắc chắn rằng khóa sẽ được giải phóng khi có ngoại lệ xảy ra bên trong khối khóa.
    Đó là bởi vì khóa sử dụng màn hình dưới mui xe và được thực hiện theo cách này :

     object __lockObj = x;
     bool __lockWasTaken = false;
     try
     {
         System.Threading.Monitor.Enter(__lockObj, ref __lockWasTaken);
         // Your code...
     }
     finally
     {
         if (__lockWasTaken) System.Threading.Monitor.Exit(__lockObj);
     }
    

    Do đó, trong mọi trường hợp, khóa được phát hành và bạn không cần phải giải phóng nó một cách thủ công (giống như bạn làm cho các trường hợp đột biến).

  2. Đối với Khóa, bạn thường sử dụng một đối tượng riêng để khóa (và nên sử dụng ).
    Điều này được thực hiện vì nhiều lý do. (Thông tin thêm: xem câu trả lời nàytài liệu chính thức ).

Vì vậy, trong trường hợp khóa, bạn không thể (vô tình có được) quyền truy cập vào đối tượng bị khóa từ bên ngoài và gây ra một số thiệt hại.
Nhưng trong trường hợp Mutex, bạn có thể, vì thông thường có một Mutex được đánh dấu công khai và được sử dụng từ bất cứ đâu.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.