2011-08-30 34 views
5

Trong cuốn sách trực tuyến luồng này: http://www.albahari.com/threading/part4.aspxHiểu không đồng bộ hóa thread chặn và Thread.MemoryBarrier

theres một ví dụ về Thread.MemoryBarrier()

class Foo 
{ 
    int _answer; 
    bool _complete; 

    void A() 
    { 
    _answer = 123; 
    Thread.MemoryBarrier(); // Barrier 1 
    _complete = true; 
    Thread.MemoryBarrier(); // Barrier 2 
    } 

    void B() 
    { 
    Thread.MemoryBarrier(); // Barrier 3 
    if (_complete) 
    { 
     Thread.MemoryBarrier();  // Barrier 4 
     Console.WriteLine (_answer); 
    } 
    } 
} 

Chúng tôi đã nhận một cuộc thảo luận xem liệu có bất kỳ chủ đề chặn xảy ra hay không?

Im suy nghĩ có một số người, đặc biệt là cho rằng

Một hàng rào đầy đủ mất khoảng mười nano giây trên một máy tính để bàn 2010-thời đại.

Mặt khác, hàng rào đầy đủ chỉ được cho disable instructions reodering and caching mà theo âm thanh của nó không được coi là chủ đề chặn, (không giống như lock nơi của nó rõ ràng là chờ đợi cho chủ đề khác để phát hành khóa trước khi nó tiếp tục, và bị chặn trong thời gian đó)

Giới thiệu về chủ đề 'chặn trạng thái' đó. im nói không phải là liệu thread có được đặt vào trạng thái bị chặn hay không, nhưng liệu có một số vấn đề đồng bộ hóa không, có nghĩa là một luồng không thể chạy trong khi không cho phép MemoryBarrier trong trường hợp này.

Ngoài ra, Id hiểu rõ từng rào cản đạt được như thế nào. Ví dụ Barrier 2 - làm thế nào chính xác nó cung cấp đảm bảo độ tươi và làm thế nào nó được kết nối với rào cản 3? Nếu ai đó sẽ giải thích chi tiết mỗi rào cản mục đích ở đây (những gì có thể có thể đi sai nếu 1 hoặc 2 hoặc 3 hoặc 4 không có) Tôi nghĩ id cải thiện sự hiểu biết của tôi về điều này rất nhiều.

CHỈNH SỬA: hầu hết rõ ràng là bây giờ những gì 1, 2 và 3 thực hiện. Tuy nhiên những gì 4 hiện 3 không phải là vẫn không rõ ràng.

Trả lời

5

Thực tế là các hướng dẫn cần có thời gian để thực thi không ngụ ý rằng một chuỗi bị chặn. Một chuỗi bị chặn khi nó được đặt cụ thể vào trạng thái bị chặn, trong đó MemoryBarrier() không làm.

Hướng dẫn của bộ xử lý thực sự ngăn việc sắp xếp lại lệnh và bộ nhớ cache xả đỏ mất thời gian, bởi vì chúng phải đợi cho bộ nhớ cache trở nên mạch lạc trở lại. Trong thời gian đó, chuỗi vẫn được coi là đang chạy.

Cập nhật: Vì vậy, hãy xem những gì thực sự xảy ra trong ví dụ và những gì mỗi rào cản bộ nhớ thực sự làm.

Khi liên kết cho biết, 1 và 4 đảm bảo rằng các câu trả lời đúng được tạo ra. Đó là bởi vì 1 đảm bảo rằng các câu trả lời được flushed vào bộ nhớ, và 4 đảm bảo rằng các cache đọc được flushed trước khi lấy các biến.

2 và 3 đảm bảo rằng nếu A chạy trước, sau đó B sẽ luôn luôn in câu trả lời. Rào cản 2 đảm bảo rằng việc ghi true bị xóa vào bộ nhớ và rào chắn 3 đảm bảo rằng các giá trị đọc được xóa trước khi thử nghiệm giá trị của _complete.

Việc xóa bộ nhớ cache và bộ nhớ phải đủ rõ ràng, vì vậy hãy xem xét sắp xếp lại hướng dẫn.Cách trình biên dịch, CLR và CPU biết rằng họ có thể sắp xếp lại các lệnh bằng cách phân tích một tập hợp các lệnh theo trình tự. Khi họ thấy hướng dẫn rào cản ở giữa một chuỗi, họ biết rằng hướng dẫn không thể di chuyển qua ranh giới đó. Điều đó đảm bảo rằng ngoài việc làm mới bộ nhớ cache, các hướng dẫn sẽ diễn ra theo đúng thứ tự.

+0

chắc chắn nó không ngụ ý rằng trực tiếp, tôi chỉ nghĩ rằng nó có thể được coi là một bằng chứng, logic của nó mà lệnh cần có thời gian để thực thi. –

+0

@Valentin Nó có thể được coi là bằng chứng, nhưng nó không phải là trường hợp ở đây :) – dlev

+0

okay, xem chỉnh sửa của tôi vào cuối câu hỏi, và trong khi chúng tôi đang ở đó, không khóa tuyên bố đặt một thread vào trạng thái bị chặn (chỉ để làm rõ mà thread bị chặn định nghĩa nhà nước)? –

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