2013-06-24 23 views
7

tôi đã tự hỏi: Khóa chỉ cho phép 1 thread để nhập một mã vùngAutoResetEvent là một thay thế Khóa trong C#?

Và chờ xử lý là cho hệ thống báo::

hiệu là khi một chờ đợi chủ đề cho đến khi nó nhận được thông báo từ khác.

Vì vậy, tôi tự nghĩ, điều này có thể được sử dụng để thay thế khóa không?

cái gì đó như:

Thread number 1 --please enter (autoreset --> autlock) 
dowork... 
finish work... 
set signal to invite the next thread 

Vì vậy, tôi đã viết này:

/*1*/ static EventWaitHandle _waitHandle = new AutoResetEvent(true); 
/*2*/ 
/*3*/ volatile int i = 0; 
/*4*/ void Main() 
/*5*/ { 
/*6*/ 
/*7*/  for (int k = 0; k < 10; k++) 
/*8*/  { 
/*9*/   var g = i; 
/*10*/   Interlocked.Increment(ref i); 
/*11*/   new Thread(() = > DoWork(g)).Start(); 
/*12*/ 
/*13*/  } 
/*14*/ 
/*15*/  Console.ReadLine(); 
/*16*/ } 
/*17*/ 
/*18*/ 
/*19*/ void DoWork(object o) 
/*20*/ { 
/*21*/  _waitHandle.WaitOne(); 
/*22*/  Thread.Sleep(10); 
/*23*/  Console.WriteLine((int) o + "Working..."); 
/*24*/  _waitHandle.Set(); 
/*25*/ 
/*26*/ } 

như bạn có thể thấy: dòng # 21, # 24 là sự thay thế cho các khóa.

Câu hỏi:

  • Có một sự thay thế hợp lệ? (không phải tôi sẽ thay thế lock, nhưng muốn biết về các kịch bản sử dụng)
  • Tôi nên sử dụng mỗi khi nào?

Cảm ơn bạn.

lạ nhưng SO không chứa một câu hỏi liên quan _lock vs EventWaitHandle_

+0

SO có câu hỏi tương tự: http://stackoverflow.com/questions/1717194/autoresetevent-manualresetevent-vs-monitor – empi

+0

@empi heh, tất cả 3 cụm từ đều có trong thành phần chung (monitor.enter vs lock, autoreset vs waithandle ....) nhưng yeah nó tương tự.tuy nhiên xin lưu ý rằng 'AutoResetEvent/waithdnales' là ** không được chia sẻ ** giữa các quá trình. người viết nhầm lẫn với Mutex. dù sao anh ta cũng sai. (về điều đó). –

+0

@empi cũng là câu trả lời được đánh giá cao nhất về sự khác biệt khi có lệnh được thiết lập (thời tiết nếu chuỗi đang chờ hay không). –

Trả lời

11

Không đến đó. Một thuộc tính quan trọng của khóa là nó cung cấp công bằng. Nói cách khác, một đảm bảo hợp lý rằng các chủ đề tranh giành cho khóa có được một sự bảo đảm rằng chúng có thể có được nó. Lớp Monitor cung cấp sự bảo đảm như vậy, được thực hiện bởi một hàng chờ đợi trong CLR. Và Mutex và Semaphore cung cấp sự bảo đảm như vậy, được thực hiện bởi hệ điều hành.

WaitHandles do không đảm bảo như vậy. Đó là rất bất lợi nếu khóa được contended, cùng một thread có thể có được nó nhiều lần và các chủ đề khác có thể chết đói mãi mãi.

Sử dụng đối tượng đồng bộ hóa thích hợp cho khóa. Các chốt chờ chỉ nên được sử dụng để báo hiệu.

+0

_fairness_ - Điều này có nghĩa rằng nếu các chủ đề: 1,5,7 (theo thứ tự) đến vùng khóa, khóa sẽ (khi được phát hành) sẽ công bằng và nó sẽ được giải phóng cho các chủ đề 1 -> 5 -> 7? (trong khi waitHandles có thể làm: 1 -> 1 -> 1 - bởi vì thread có thể có ưu tiên quá trình/luồng cao hơn?) –

+0

Có một vài câu hỏi liên quan đến APC nên đây không phải là trường hợp nghiêm trọng. Nhưng có, đó là thứ tự bình thường trong đó chủ đề có được một khóa khi đối tượng đồng bộ hứa hẹn sự công bằng. –

+0

Hans Tôi cũng đọc một nơi nào đó rằng: nếu có ** không có chủ đề khác ** muốn khóa - tài nguyên hạt nhân (hoặc cái gì đó như thế) thậm chí không được thực hiện .... bạn có thể tham khảo tôi cho đúng thời hạn không? –

1

Có thể, nhưng nó là chậm hơn nhiều so với khóa() và khó khăn hơn nhiều để duy trì.

Nhân tiện, bạn không bao giờ nên đọc giá trị trực tiếp khi sử dụng các phương pháp liên khóa để duy trì nó.

Mã của bạn sẽ trông như thế này:

var g = Interlocked.Increment(ref i); 

Sau đó g sẽ chứa giá trị tăng lên chứ không phải là một giá trị trước đó abitrary.

Các vấn đề liên quan