Việc triển khai mutlock spinlock có vẻ ổn với tôi. Tôi nghĩ rằng họ có định nghĩa về số có được và phát hành hoàn toàn sai.
Dưới đây là giải thích rõ ràng nhất về các mô hình nhất quán về mua/phát hành mà tôi biết: Gharachorloo; Lenoski; Laudon; Gibbons; Gupta; Hennessy: Memory consistency and event ordering in scalable shared-memory multiprocessors, Int'l Symp Comp Arch, ISCA(17):15-26, 1990, doi 10.1145/325096.325102. (Công cuộc đổi là phía sau tường phí ACM Các liên kết thực tế là một bản sao không đằng sau một tường phí..)
Nhìn vào Điều kiện 3.1 tại mục 3.3 và Hình kèm theo 3:
- trước khi bình thường tải hoặc truy cập cửa hàng được phép để thực hiện đối với bất kỳ bộ xử lý khác, tất cả các truy cập Acquire trước phải được thực hiện, và
- trước khi truy cập phát hành được phép thực hiện với đối với bất kỳ bộ xử lý khác, tất cả trước đó bình thường tải một d truy cập cửa hàng phải được thực hiện và
- quyền truy cập đặc biệt [liên tục] phù hợp với tôn trọng với nhau.
Vấn đề là: mua và giải phóng liên tục tuần tự (tất cả các chủ đề trên toàn cầu đồng ý về thứ tự mua và phát hành đã xảy ra.) Tất cả các chủ đề đều đồng ý rằng nội dung xảy ra giữa việc mua và phát hành trên thread cụ thể đã xảy ra giữa việc mua và phát hành.Nhưng các tải và lưu trữ thông thường sau một bản phát hành được phép di chuyển (bằng phần cứng hoặc trình biên dịch) phía trên bản phát hành và tải và lưu trữ bình thường trước việc mua lại được phép di chuyển (bằng phần cứng hoặc trình biên dịch) sau khi có được.
Trong C++ standard (Tôi đã sử dụng liên kết đến bản nháp tháng 1 năm 2012) phần có liên quan là 1,10 (trang 11 đến 14).
Định nghĩa của xảy ra trước khi được thiết kế để được mô hình hóa sau Lamport; Time, Clocks, and the Ordering of Events in a Distributed System, CACM, 21(7):558-565, Jul 1978. C++ mua lại tương ứng với Lamport của nhận, C++ phiên tương ứng với Lamport của gửi. Lamport đặt tổng số thứ tự trên chuỗi sự kiện trong một chuỗi đơn, trong đó C++ phải cho phép một phần đơn hàng (xem Phần 1.9, Đoạn 13-15, trang 10 cho định nghĩa C++ là được sắp xếp trước.) Tuy nhiên, được sắp xếp theo thứ tự trước khi đặt hàng là khá nhiều điều bạn mong đợi. Các câu lệnh được sắp xếp thứ tự theo thứ tự chúng được đưa ra trong chương trình. Phần 1.9, đoạn 14: "Mọi tính toán giá trị và mặt bên được kết hợp với một biểu thức đầy đủ được sắp xếp trước mỗi giá trị tính toán và e ff ect kết hợp với biểu thức đầy đủ tiếp theo được đánh giá."
Toàn bộ điểm của Mục 1.10 là chương trình dữ liệu đua miễn phí tạo ra cùng giá trị được xác định như thể chương trình được chạy trên máy có bộ nhớ liên tục và không có trình biên dịch sắp xếp lại. Nếu có một cuộc đua dữ liệu thì chương trình không có nghĩa ngữ nghĩa nào cả. Nếu không có cuộc đua dữ liệu thì trình biên dịch (hoặc máy) được phép sắp xếp lại các hoạt động không đóng góp vào ảo ảnh về tính nhất quán tuần tự.
Mục 1.10, đoạn 21 (trang 14) cho biết: Chương trình không phải là dữ liệu đua miễn phí nếu có một cặp truy cập A và B từ các chủ đề khác nhau để phản đối X, ít nhất một trong các truy cập đó một tác dụng phụ, và không A xảy ra - trước B, cũng không B xảy ra trước khi A. Nếu không, chương trình sẽ không có dữ liệu.
Đoạn 6-20 đưa ra định nghĩa rất cẩn thận về mối quan hệ xảy ra trước đó. Định nghĩa chính là Đoạn 12:
"Một đánh giá Một xảy ra trước khi đánh giá B nếu:
- A được giải mã trước khi B, hoặc
- Một liên thread xảy ra trước khi B."
Vì vậy, nếu có được (cùng một chuỗi) với bất kỳ tuyên bố nào khác, thì việc mua phải xuất hiện để xảy ra trước tuyên bố đó. (Bao gồm cả nếu tuyên bố đó thực hiện ghi.)
Tương tự như vậy: nếu có nhiều tuyên bố là được trình tự trước (cùng một chuỗi) bản phát hành, thì tuyên bố đó phải xuất hiện trước khi phát hành. (Bao gồm nếu câu lệnh đó chỉ thực hiện tính toán giá trị (đọc).)
Lý do mà các trình biên dịch là phép di chuyển tính khác từ sau khi một thông cáo tới trước khi phát hành (hoặc từ trước khi tiếp cận được vào sau một đạt được) là vì thực tế rằng những hoạt động đặc biệt làm không có một mối liên hệ xảy ra trước mối quan hệ (vì chúng nằm ngoài phần quan trọng). Nếu họ chạy đua ngữ nghĩa là không xác định, và nếu họ không đua (vì họ không được chia sẻ) sau đó bạn không thể nói chính xác khi họ đã xảy ra đối với việc đồng bộ hóa.
Đó là một cách rất dài để nói rằng: định nghĩa của cppreference.com về việc mua và phát hành là sai. Chương trình ví dụ của bạn không có điều kiện chạy dữ liệu và PANIC không thể xảy ra.
Bạn nghĩ điều này có thể như thế nào? Thứ tự chính xác của sự kiện (bao gồm cả khóa và mở khóa) mà bạn tưởng tượng là gì? –
Tôi đã thêm khóa vào dấu vết ở trên. Tôi tưởng tượng rằng post-obtain-write tại (5) có thể được thực hiện trước (4). –