tôi đã làm CLR hỗ trợ các lớp học & cho luồng trong DotGNU và tôi có một vài suy nghĩ ...
Trừ khi bạn yêu cầu khóa quá trình chéo bạn nên luôn luôn tránh sử dụng Mutex & Semaphores. Các lớp này trong .NET là các trình bao bọc xung quanh Win32 Mutex và Semaphores và có trọng lượng khá nặng (chúng yêu cầu chuyển đổi ngữ cảnh vào Kernel vốn đắt - đặc biệt nếu khóa của bạn không bị tranh chấp).
Như những người khác được đề cập, các C# khóa tuyên bố là trình biên dịch ma thuật cho Monitor.Enter và Monitor.Exit (hiện có trong một thử/cuối cùng).
Màn hình có cơ chế tín hiệu/chờ đợi đơn giản nhưng mạnh mẽ mà Mutexes không có thông qua các phương thức Monitor.Pulse/Monitor.Wait. Tương đương Win32 sẽ là các đối tượng sự kiện thông qua CreateEvent mà thực sự cũng tồn tại trong .NET như WaitHandles. Mô hình Pulse/Wait tương tự như pthread_signal và pthread_wait của Unix nhưng nhanh hơn vì chúng có thể là các hoạt động chế độ người dùng hoàn toàn trong trường hợp không được tranh chấp.
Monitor.Pulse/Wait rất dễ sử dụng. Trong một chủ đề, chúng ta khóa một đối tượng, kiểm tra cờ/state/property và nếu nó không phải là những gì chúng ta đang mong đợi, hãy gọi Monitor.Wait để giải phóng khóa và chờ cho đến khi một xung được gửi đi. Khi chờ đợi trả về, chúng tôi lặp lại và kiểm tra lại cờ/trạng thái/thuộc tính. Trong chủ đề khác, chúng ta khóa đối tượng bất cứ khi nào chúng ta thay đổi cờ/state/property và sau đó gọi PulseAll để đánh thức bất kỳ chủ đề nghe nào.
Thông thường chúng tôi muốn các lớp của chúng tôi là chủ đề an toàn, vì vậy chúng tôi đặt khóa trong mã của chúng tôi. Tuy nhiên, thường là trường hợp lớp của chúng ta sẽ chỉ được sử dụng bởi một luồng. Điều này có nghĩa là các ổ khóa không cần thiết làm chậm mã của chúng tôi ... đây là nơi tối ưu hóa thông minh trong CLR có thể giúp cải thiện hiệu suất.
Tôi không chắc về việc triển khai khóa của Microsoft nhưng trong DotGNU và Mono, cờ trạng thái khóa được lưu trữ trong tiêu đề của mọi đối tượng. Mỗi đối tượng trong .NET (và Java) có thể trở thành một khóa để mọi đối tượng cần hỗ trợ điều này trong tiêu đề của chúng. Trong việc triển khai DotGNU, có một lá cờ cho phép bạn sử dụng một hashtable toàn cục cho mọi đối tượng được sử dụng như một khóa - điều này có lợi cho việc loại bỏ chi phí 4 byte cho mọi đối tượng. Đây không phải là tuyệt vời cho bộ nhớ (đặc biệt là cho các hệ thống nhúng mà không phải là luồng rất nhiều) nhưng có một hit về hiệu suất.
Cả Mono và DotGNU hiệu quả sử dụng mutexes để thực hiện khóa/chờ đợi nhưng sử dụng một phong cách spinlock compare-and-exchange hoạt động để loại bỏ sự cần thiết phải thực hiện một khóa cứng trừ khi thực sự cần thiết:
Bạn có thể xem ví dụ về màn hình như thế nào có thể được thực hiện ở đây:
http://cvs.savannah.gnu.org/viewvc/dotgnu-pnet/pnet/engine/lib_monitor.c?revision=1.7&view=markup
liên kết này đã giúp tôi rất nhiều: http://www.albahari.com/threading/ – Raphael