2015-05-27 14 views
6

Có an toàn khi sử dụng bộ định tính :volatile-mutable với deftype trong một chương trình một luồng không? Đây là theo dõi tới this question, this onethis one. (Đó là một câu hỏi Clojure, nhưng tôi đã thêm thẻ "Java" vì các lập trình viên Java cũng có thể có thông tin chi tiết về nó.)Rủi ro của các trường dễ bay hơi trong các bối cảnh đơn luồng?

Tôi nhận thấy rằng tôi có thể tăng hiệu suất đáng kể trong một chương trình làm việc trên bằng cách sử dụng :volatile-mutable trường trong một deftype chứ không phải là nguyên tử, nhưng tôi lo lắng vì docstring cho deftype nói:

Lưu ý rõ rằng các lĩnh vực có thể thay đổi là vô cùng khó khăn để sử dụng một cách chính xác, và chỉ xuất hiện để tạo điều kiện việc xây dựng các cấu trúc cấp cao hơn, chẳng hạn như các loại tham chiếu của Clojure, trong chính Clojure . Chúng chỉ dành cho các chuyên gia - nếu ngữ nghĩa và tác động của: dễ biến đổi hoặc không thể đồng bộ hóa có thể thay đổi không ngay lập tức rõ ràng với bạn, bạn không nên sử dụng chúng.

Trong thực tế, ngữ nghĩa và tác động của :volatile-mutablekhông ngay lập tức rõ ràng đối với tôi.

Tuy nhiên, chương 6 của Clojure Lập trình, bởi Emerick, Carper, và Grand nói:

"bay hơi" ở đây có ý nghĩa tương tự như sửa đổi lĩnh vực dễ bay hơi trong Java: đọc và viết là nguyên tử và phải được thực hiện theo thứ tự chương trình; tức là, chúng không thể được sắp xếp lại bởi trình biên dịch JIT hoặc bởi CPU. Các chất dễ bay hơi do đó không đáng ngạc nhiên và an toàn chỉ - nhưng không được phối hợp và vẫn hoàn toàn mở cho các điều kiện chủng tộc.

Điều này dường như ngụ ý rằng miễn là truy cập vào một trường đơn lẻ có thể biến đổi bất thường deftype diễn ra trong một chuỗi duy nhất, không có gì phải lo lắng đặc biệt. (Không có gì là đặc biệt, trong đó tôi vẫn phải cẩn thận về cách tôi xử lý trạng thái nếu tôi có thể sử dụng các trình tự lười biếng.) Vì vậy, nếu không có gì giới thiệu song song trong chương trình Clojure của tôi, sẽ không có nguy hiểm đặc biệt nào khi sử dụng deftype với :volatile-mutable.

Điều đó có đúng không? Tôi không hiểu những nguy hiểm gì?

+2

Nếu bạn có một sợi java đơn, và 'volatile' có ý nghĩa tương tự như java của biến động - bạn không cần phải 'volatile' ở tất cả. – ZhongYu

+0

atomicity là một vấn đề khác. bạn có thể có các vấn đề tương tranh ngay cả với một chuỗi. Nhưng tôi không quen với Clojure nên tôi không thể bình luận. – ZhongYu

+0

bayou.io: Từ khóa dễ bay hơi cũng thực thi rằng thứ tự chương trình của các cuộc gọi trên các biến biến động không thể được sắp xếp lại. Điều đó có thể có một số sử dụng trong một số trường hợp, tuy nhiên tôi không thể nghĩ ra một. –

Trả lời

3

Chính xác, an toàn. Bạn chỉ cần chắc chắn rằng ngữ cảnh của bạn thực sự đơn luồng. Đôi khi nó không phải là dễ dàng để đảm bảo điều đó.

Không có rủi ro nào về an toàn chủ đề hoặc nguyên tử khi sử dụng trường có thể thay đổi (hoặc chỉ có thể thay đổi) trong ngữ cảnh một luồng, vì chỉ có một chuỗi sao cho không có hai chủ đề viết mới giá trị cho trường này cùng một lúc hoặc một chuỗi ghi một giá trị mới dựa trên các giá trị lỗi thời.

Như những người khác đã chỉ ra trong các ý kiến ​​bạn có thể muốn chỉ cần sử dụng một trường :unsynchronized-mutable để tránh những chi phí được giới thiệu bởi biến động.Chi phí đó xuất phát từ thực tế là mọi chữ viết phải là cam kết với bộ nhớ chính thay vì bộ nhớ cục bộ của luồng. Xem this answer để biết thêm thông tin về điều này.

Đồng thời, bạn không nhận được gì bằng cách sử dụng dễ bay hơi trong một ngữ cảnh đơn luồng vì không có khả năng có một chuỗi ghi giá trị mới sẽ không bị "nhìn thấy" bởi chủ đề khác đọc cùng một trường. Đó là những gì dễ bay hơi được dự định, nhưng nó không liên quan trong bối cảnh một luồng đơn.

Cũng lưu ý rằng clojure 1,7 giới thiệu volatile! nhằm cung cấp một "hộp ổn định cho việc quản lý nhà nước" như một sự thay thế nhanh hơn để nguyên tử, với một giao diện tương tự nhưng không có nó là so sánh và ngữ nghĩa hoán đổi. Sự khác biệt duy nhất khi sử dụng nó là bạn gọi vswap!vreset! thay vì swap!reset!. Tôi sẽ sử dụng nó thay vì deftype với ^:volatile-mutable nếu tôi cần một biến động.

+0

Cảm ơn - trong số những thứ khác, tôi không biết về 'biến động!', Và rất hữu ích khi biết về vấn đề bộ nhớ đệm. – Mars

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