2011-12-28 29 views
8

Tôi bị nhầm lẫn trên volatile đối với loại tham chiếu.dễ bay hơi đối với loại tham chiếu trong .net 4.0

Tôi hiểu rằng đối với loại nguyên thủy, volatile có thể phản ánh thay đổi giá trị từ một chuỗi khác ngay lập tức. Đối với loại tham chiếu, nó có thể phản ánh những thay đổi địa chỉ ngay lập tức. Tuy nhiên, những gì về nội dung của đối tượng. Chúng vẫn được lưu trong bộ nhớ cache?

(Giả sử List.Add() là một hoạt động nguyên tử)

Ví dụ, tôi có:

class A 
{ 
    volatile List<String> list; 
    void AddValue() 
    { 
     list.Add("a value"); 
    } 

} 

Nếu một thread gọi hàm AddValue, địa chỉ của danh sách không thay đổi, sẽ thread khác được cập nhật về thay đổi "nội dung" của danh sách hoặc nội dung có thể được lưu vào bộ nhớ cache cho mỗi chuỗi và nó không cập nhật cho các chủ đề khác?

+0

Tôi không chắc chắn về điều này, nhưng tôi đoán là danh sách đó thực sự chỉ là một con trỏ (địa chỉ), khi nội dung được cập nhật nó ngay lập tức được phản ánh ở mọi nơi, vì nội dung sẽ nằm trong heap, thay đổi địa chỉ ngăn xếp được thay đổi, và tôi nghĩ rằng có thể cư trú trên một lõi đơn. Nhưng, như đã nói, không có chuyên gia. Nó chỉ là một dự đoán. – Alxandr

+0

Ngoài ra, như một lưu ý phụ. biến động dễ bay hơi của rất nhiều tối ưu hóa. Rất nhiều tối ưu hóa. Một số người không nên sử dụng các công cụ sửa đổi dễ bay hơi, mà chỉ sử dụng volatileread và volatilewrite khi cần (một số phương thức tĩnh toàn cục được tìm thấy trên một lớp trong không gian tên hệ thống, có thể được tìm thấy trên google). – Alxandr

+1

@Alxandr: Hãy cẩn thận. Đọc dễ bay hơi và viết dễ bay hơi là các phương thức đắt tiền có khả năng để gọi và chúng tạo ra * hàng rào đầy đủ *, không phải là hàng rào nửa mà người ta mong đợi. Nếu bạn đang viết mã không có khóa vì lý do hiệu suất (và lý do nào khác bạn phải làm điều điên rồ này?) Hoàn toàn có thể là VolatileRead và VolatileWrite tệ hơn. Bạn phải ghi lại cẩn thận. –

Trả lời

2

Từ khóa volatile không ảnh hưởng đến nội dung của danh sách (hoặc chính xác hơn, đối tượng đang được tham chiếu).

Nói về đã cập nhật/không được cập nhật cho một chuỗi khác là sự đơn giản hóa những gì đang xảy ra. Bạn nên sử dụng câu lệnh lock để đồng bộ hóa quyền truy cập vào danh sách được chia sẻ. Nếu không, bạn có hiệu quả phải đối mặt với điều kiện chủng tộc có thể dẫn đến sự cố chương trình. Lớp List<T> không phải là chủ đề an toàn.

6

Tệ hơn thế.

Nếu bạn đồng thời truy cập một đối tượng không an toàn với luồng, chương trình của bạn có thể thực sự bị lỗi. Nhận được thông tin lỗi thời không phải là kết quả tiềm năng tồi tệ nhất.

Khi chia sẻ đối tượng thư viện lớp cơ sở .NET giữa các chủ đề, bạn thực sự không có lựa chọn nào khác ngoài việc sử dụng khóa. Đối với lập trình không khóa, bạn cần thay đổi xâm lấn đối với cấu trúc dữ liệu của bạn ở các mức thấp nhất.

19

Tôi hiểu rằng đối với loại nguyên thủy, dễ bay hơi có thể phản ánh những thay đổi giá trị từ một thread ngay

Bạn hiểu sai trong ít nhất ba cách. Bạn không nên cố gắng sử dụng dễ bay hơi cho đến khi bạn hiểu rõ hơn mọi thứ về các kiểu bộ nhớ yếu, có được và giải phóng ngữ nghĩa và cách chúng ảnh hưởng đến chương trình của bạn.

Trước hết, hãy rõ ràng là dễ bay hơi ảnh hưởng đến biến, không phải giá trị.

Thứ hai, dễ bay hơi không ảnh hưởng đến các biến chứa giá trị của các loại giá trị khác với các biến có ảnh hưởng đến các biến chứa tham chiếu.

Thứ ba, dễ bay hơi không có nghĩa là thay đổi giá trị từ các chủ đề khác được hiển thị ngay lập tức. Dễ bay hơi có nghĩa là các biến có có được và phát hành ngữ nghĩa. Biến động ảnh hưởng đến thứ tự trong đó các tác dụng phụ của đột biến bộ nhớ có thể được quan sát xảy ra từ một chủ đề cụ thể.Ý tưởng cho rằng tồn tại một trật tự phổ biến nhất quán của các đột biến và những đột biến đó theo thứ tự có thể được quan sát ngay lập tức từ tất cả các luồng không phải là một sự đảm bảo được thực hiện bởi mô hình bộ nhớ.

Tuy nhiên, nội dung của đối tượng thì sao?

Điều gì về nó? Vị trí lưu trữ được đề cập bởi một biến biến động của kiểu tham chiếu không cần phải có bất kỳ đặc tính luồng đặc biệt nào.

Nếu một chuỗi gọi hàm AddValue, địa chỉ của danh sách không thay đổi, một chuỗi khác sẽ được cập nhật về thay đổi "nội dung" của danh sách.

Không. Tại sao nó? Chủ đề khác có thể nằm trên một bộ xử lý khác và bộ nhớ cache của bộ xử lý đó có thể đã tải trước trang chứa địa chỉ của mảng đang sao lưu danh sách. Việc tắt danh sách có thể đã thay đổi vị trí lưu trữ chứa địa chỉ của mảng để tham chiếu đến một số vị trí hoàn toàn khác.

Tất nhiên, lớp danh sách không phải là chủ đề an toàn ngay từ đầu. Nếu bạn không khóa truy cập vào danh sách thì danh sách có thể chỉ đơn giản là sụp đổ và chết khi bạn cố gắng làm điều này.

Bạn không cần dễ bay hơi; những gì bạn cần là để đưa khóa chuỗi xung quanh quyền truy cập vào danh sách. Kể từ khi khóa sợi tạo ra hàng rào đầy đủ, bạn không nên cần một nửa hàng rào được giới thiệu bởi dễ bay hơi.

+0

Cảm ơn rất nhiều Eric. Dựa trên sự hiểu biết của tôi về lời giải thích của bạn, dễ bay hơi được sử dụng để ngăn chặn tác dụng phụ của đột biến bộ nhớ. Tuy nhiên, những gì được sử dụng để ngăn chặn bản sao CPU đăng ký giá trị bộ nhớ. Trong đa lõi CPU, hai lõi nhiều bộ nhớ cache hai bản sao của biến (ví dụ như một int), nếu một trong số họ cập nhật nó, làm thế nào sẽ nhận được nó. Chúng ta có cần làm bất cứ điều gì trong mã C# hay nó được tự động thực hiện bởi .net? THnaks một lần nữa. – Frank

+1

@Feng: Bạn đã hiểu lầm tôi. Tôi không nói rằng "dễ bay hơi" ngăn chặn các tác dụng phụ của đột biến bộ nhớ; làm thế nào trên trái đất nó có thể làm điều đó? Thay vào đó, "dễ bay hơi" ảnh hưởng đến * thứ tự * trong đó những đột biến đó có thể được * quan sát * xảy ra. Nó làm như vậy bằng cách gây ra có được và phát hành ngữ nghĩa vào biến đọc và viết. ** Nếu bạn không hiểu làm thế nào có được và phát hành ngữ nghĩa làm việc sau đó bạn không nên sử dụng dễ bay hơi. ** Tất nhiên để làm như vậy nó cũng tắt bộ nhớ đệm tối ưu hóa. –

1

Nhìn vào http://www.albahari.com/threading/part4.aspx#_The_volatile_keyword để có giải thích tốt về những gì dễ bay hơi thực sự và cách nó tác động đến các trường.

Toàn bộ phần luồng trên trang web đó phải đọc, nó chứa rất nhiều thông tin hữu ích đã tỏ ra rất hữu ích cho tôi khi tôi thiết kế phần mềm đa luồng.

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