2012-01-16 13 views
5

Hiện tại, tôi đang học cho một bài kiểm tra đa luồng. Tôi đọc the good threading article of albahari. Tôi đã có một câu hỏi tại việc sử dụng màn hình - tại sao ở đây được sử dụng một vòng lặp ở vị trí của một nếu?Monitor.Wait - trong khi hoặc nếu?

lock (_locker) 
{ 
    while (!_go) //why while and not if? 
    Monitor.Wait (_locker); // _lock is released 
    // lock is regained 
    ... 
} 

Tôi nghĩ, nếu đủ sẽ đủ.

Tôi sợ rằng tôi không hiểu hoàn toàn bài viết.

// Sửa Ví dụ-Code:

class SimpleWaitPulse 
{ 
    static readonly object _locker = new object(); 
    static bool _go; 

    static void Main() 
    {        // The new thread will block 
    new Thread (Work).Start();  // because _go==false. 

    Console.ReadLine();   // Wait for user to hit Enter 

    lock (_locker)     // Let's now wake up the thread by 
    {        // setting _go=true and pulsing. 
     _go = true; 
     Monitor.Pulse (_locker); 
    } 
    } 

    static void Work() 
    { 
    lock (_locker) 
     while (!_go) 
     Monitor.Wait (_locker); // Lock is released while we’re waiting 

    Console.WriteLine ("Woken!!!"); 
    } 
} 
+1

"Nếu" chỉ kiểm tra một lần. Vòng lặp "while" sẽ tiếp tục kiểm tra. Nếu không đợi. Trong khi chờ đợi. – DOK

+0

Xin chào DOK - cảm ơn lời giải thích của bạn. Nhưng tôi nghĩ, hoạt động Monitor.Wait sẽ chỉ được thực thi một lần. Nó sẽ chờ tín hiệu Pulse. Vì vậy, tôi thấy không có lý do cho một thời gian :-( – bitsmuggler

+0

Nó phụ thuộc vào phần còn lại của chương trình, giống như những gì chính xác là '_go' nghĩa vụ phải có nghĩa là, và khi nào bạn thiết lập nó – svick

Trả lời

5

Nó chỉ phụ thuộc vào tình hình. Trong trường hợp này, mã chỉ đợi _gođúng.

Mỗi lần _locker được xung nó sẽ kiểm tra xem nếu _go đã được thiết lập để đúng. Nếu _go vẫn là false, nó sẽ đợi xung tiếp theo.

Nếu một nếu đã được sử dụng thay vì một khi, nó sẽ chỉ chờ đợi một lúc (hoặc không gì cả nếu _go là đã đúng), và sau đó sẽ tiếp tục sau khi một xung, không phụ thuộc vào mới trạng thái _go.

Vậy cách bạn sử dụng Monitor.Wait() tùy thuộc hoàn toàn vào các nhu cầu cụ thể của bạn.

+0

Cảm ơn! Điều đó đã giúp tôi. – bitsmuggler

3

Nó thực sự chỉ phụ thuộc vào tình huống. Nhưng trước tiên, chúng ta cần làm rõ cách Màn hình hoạt động. Khi một luồng tiến hành báo hiệu một luồng thông qua Monitor.Pulse(), thường không đảm bảo rằng luồng được báo hiệu sẽ thực sự chạy tiếp theo. Điều này có nghĩa là có thể cho các luồng khác chạy trước luồng đã được báo hiệu và thay đổi điều kiện theo đó nó được chấp thuận cho luồng được báo hiệu tiến hành. Điều này có nghĩa là luồng tín hiệu vẫn cần phải kiểm tra xem có an toàn để nó tiếp tục sau khi được đánh thức (tức là vòng lặp while) hay không. Tuy nhiên, một số vấn đề đồng bộ hiếm gặp cho phép bạn đưa ra giả định rằng khi một luồng đã được báo hiệu để đánh thức (tức là Monitor.Pulse()), không có luồng nào khác có khả năng thay đổi điều kiện mà nó an toàn để tiến hành (ví dụ: . Nếu điều kiện).

2

tôi đã viết một bài viết mà có thể giúp đỡ ở đây: Wait and Pulse demystified

Có nhiều đang diễn ra hơn là ngay lập tức rõ ràng.

1

Tôi có câu hỏi về cách sử dụng màn hình - tại sao lại sử dụng vòng lặp trong địa điểm nếu có?

Có một quy tắc nổi tiếng khi làm việc với PulseWait đó khẳng định rằng khi nghi ngờ thích while trên một if. Rõ ràng, hoặc là một trong những sẽ làm việc trong trường hợp này, nhưng trong hầu hết mọi tình huống khác while là bắt buộc. Trong thực tế, có rất ít trường hợp (nếu có) khi sử dụng vòng lặp while sẽ tạo ra kết quả không chính xác. Đó là cơ sở cho quy tắc chung này. Tác giả đã sử dụng vòng lặp while vì anh ấy đang cố gắng gắn bó với mẫu cố định và đúng. Thậm chí anh ấy còn cung cấp mẫu trong cùng một bài viết.Dưới đây là nó là:

lock (_locker) 
    while (<blocking-condition>) 
    Monitor.Wait (_locker); 
0

Cách đơn giản nhất để viết mã đúng với Monitor.Wait là giả định hệ thống sẽ coi nó như là "cố vấn", và cho rằng hệ thống tùy tiện có thể đánh thức sợi bất kỳ chờ đợi bất cứ lúc nào nó có thể có được khóa, không quan tâm đến việc liệu Pulse đã được gọi hay chưa. Hệ thống thường là sẽ không làm như vậy, tất nhiên, nhưng nếu một chương trình đang sử dụng WaitPulse đúng cách, tính chính xác của nó sẽ không bị ảnh hưởng khi có các cuộc gọi Wait tự động thoát sớm mà không có lý do gì. Về cơ bản, người ta nên xem Wait như một phương tiện để nói cho hệ thống "Tiếp tục thực hiện quá khứ ở đây sẽ là một sự lãng phí thời gian trừ khi hoặc cho đến khi người khác gọi Pulse".

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