2009-07-23 28 views
7
class StopIt 
{ 
    private bool stop; 

    void Loop() 
    { 
    while (!stop) 
    { 
     // work 
    } 
    } 

    void Stop() 
    { 
    stop = true; 
    } 
} 

Về cơ bản, nếu phương pháp Loop đang chạy trong một luồng và Dừng được gọi từ một phương thức khác sẽ dừng hoạt động đúng cách? Tôi hiểu rằng bool đọc/ghi là nguyên tử. Nhưng, là đủ? Nếu vòng lặp thread không dừng lại ngay lập tức thì có vấn đề. Tôi có nên đánh dấu dừng biến động không?Là một hoạt động nguyên tử đủ

+0

Quy tắc của tôi: nếu bạn không biết chính xác những gì có nghĩa là dễ bay hơi, bạn không nên cố gắng viết các chương trình khóa miễn phí. Vì bạn đang đặt câu hỏi, bạn không biết nó có nghĩa là gì. Vì vậy, không cố gắng viết một chương trình không khóa. Hãy an toàn. Sử dụng khóa. Khóa chỉ đắt tiền khi tranh luận; Đừng cố gắng làm cho nó không khóa cho đến khi bạn chắc chắn rằng (1) bạn có vấn đề về hiệu suất (2) khóa là nguyên nhân của vấn đề và (3) bạn hiểu những gì có nghĩa là dễ bay hơi xuống mức phần cứng bộ vi xử lý. –

+0

Tôi không nên sử dụng khóa khi dừng truy cập? Nếu có, thì làm cách nào để khóa truy cập đọc trong vòng lặp while? –

+1

@yummy: rất khó để đọc khi có vẻ như bây giờ, vì bạn truy cập trực tiếp vào trường trong vòng lặp while. Nếu bạn đóng gói mà đọc trong một tài sản (hoặc một phương pháp), bạn có thể sử dụng một khóa để đọc valu. –

Trả lời

10

Có, bạn chắc chắn nên đánh dấu stop là dễ bay hơi.

Nguyên nhân không đủ - nó không đảm bảo rằng một chuỗi sẽ bao giờ "thấy" những thay đổi được thực hiện bởi một chủ đề khác.

Trong khi hiểu biết của tôi về volatile hiện đang trải qua một số phẫu thuật, bạn có thể khoảng nghĩ về ghi vào biến dễ bay hơi là "đảm bảo người khác có thể thấy điều này ngay lập tức!" và đọc từ biến biến động là "Tôi muốn xem giá trị mới nhất!"

Không làm stop dễ bay hơi, vòng lặp đó có thể tiếp tục mãi mãi, ngay cả khi Stop() được gọi trong một chuỗi khác. Về cơ bản JIT khá hợp lý có thể đọc biến vào sổ đăng ký và sau đó chỉ cần đọc từ sổ đăng ký mãi mãi. Trong thực tế, nếu "công việc" bao giờ liên quan đến việc gọi một phương pháp không nội tuyến, tôi tin rằng JIT hiện đang bị buộc phải đọc một cách dễ bay hơi, nhưng đó chỉ là giới hạn thực tế hiện tại ... nên làm cho nó dễ bay hơi.

+0

Làm cách nào để một chủ đề có thể truy cập vào những gì sẽ xảy ra ở người khác? – KdgDev

+0

Điều ngược lại cũng đúng: dễ bay hơi không đủ cho nguyên tử! – Noldorin

+0

@Noldorin: Không liên quan trong trường hợp này, khi ghi vào boolean * sẽ * là nguyên tử dựa trên phần 12.6.6 của phân vùng ECMA 335 1. –

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