Sự khác biệt giữa hoạt động nguyên tử và an toàn luồng?


10

Từ các cuộc thảo luận tôi đã thấy có vẻ như hoạt động nguyên tửan toàn luồng là như nhau, nhưng rất nhiều người nói rằng chúng khác nhau. Bất cứ ai có thể cho tôi biết sự khác biệt nếu có một?


4
Hoạt động nguyên tử sẽ giúp đảm bảo an toàn luồng, nhưng làm thế nào chúng có thể là điều tương tự ? Một "luồng" không giống như một "hoạt động".
user50849

Câu trả lời:


11

Hoạt động nguyên tử là một cách để đạt được sự an toàn của luồng bằng cách sử dụng một số loại khóa như Mutexes hoặc Semaphores sử dụng hoạt động nguyên tử trong nội bộ hoặc bằng cách thực hiện đồng bộ hóa khóa miễn phí bằng cách sử dụng hàng rào nguyên tử và bộ nhớ.

Vì vậy, các hoạt động nguyên tử trên các loại dữ liệu nguyên thủy là một công cụ để đạt được sự an toàn của luồng nhưng không đảm bảo an toàn luồng tự động vì thông thường bạn có nhiều hoạt động dựa vào nhau. Bạn phải đảm bảo rằng các thao tác này được thực hiện mà không bị gián đoạn, ví dụ như sử dụng Mutexes.

Đúng, viết một trong những kiểu dữ liệu nguyên tử này trong c # là luồng an toàn, nhưng điều đó không làm cho chức năng bạn sử dụng chúng trong luồng an toàn. Nó chỉ đảm bảo rằng việc ghi đơn được thực thi chính xác ngay cả khi một luồng thứ hai truy cập nó "cùng một lúc". Không bao giờ ít hơn, lần đọc tiếp theo từ luồng hiện tại không được đảm bảo để có được giá trị được viết trước đó như một luồng khác có thể đã được ghi cho nó, chỉ có điều giá trị đọc là hợp lệ.


Là int, bool, float là chủ đề an toàn hay nguyên tử?
dùng960567

1
@ user960567 - kiểu dữ liệu chỉ là: kiểu dữ liệu. Tùy thuộc vào trình biên dịch để quyết định cách truy cập chúng. Hãy nghĩ về một int64 trên CPU 8086.
mouviciel

2
Trong C # cụ thể, câu hỏi được gắn thẻ, đọc và ghi phải là nguyên tử trên các kiểu dữ liệu cơ bản. Xem Ecma 334
user50849

2
Và vâng, viết một trong những kiểu dữ liệu nguyên tử này trong c # là luồng an toàn, nhưng điều đó không làm cho chức năng bạn sử dụng chúng trong luồng an toàn. Nó chỉ đảm bảo rằng việc ghi đơn được thực thi chính xác ngay cả khi một luồng thứ hai truy cập nó "cùng một lúc". Không bao giờ ít hơn, lần đọc tiếp theo từ luồng hiện tại không được đảm bảo để có được giá trị được viết trước đó như một luồng khác có thể đã được ghi cho nó, chỉ có điều giá trị đọc là hợp lệ.
Archy

4
x = 5 là nguyên tử trong c #. Nhưng ngay sau khi hoạt động này, nó có thể được ghi đè. x = x + 1 được thực hiện bởi 1. tải x vào thanh ghi 2. tăng x trong thanh ghi 3. lưu x vào bộ nhớ. Nếu một luồng thứ hai thực hiện cùng một việc cùng một lúc, cả hai sẽ tải cùng một giá trị, tăng nó và lưu trữ nó dẫn đến x chỉ được tăng một lần thay vì hai lần. InterlockedIncrement sử dụng một lệnh xử lý đặc biệt để thực hiện gia tăng nguyên tử hoặc đảm bảo điều này bằng cách sử dụng cơ chế khóa, ví dụ CAS, để đảm bảo rằng trong khi giá trị mới không được ghi thì không có luồng nào khác có thể đọc giá trị cũ.
Archy

3

Nguyên tử và an toàn luồng là hai thứ khác nhau. Nguyên tử đề cập đến chất lượng "tất cả hoặc không có gì" của một hoạt động; nếu một hoạt động không thể được thực hiện thành công 100%, thì hệ thống sẽ vẫn ở trạng thái chung trước khi bất kỳ phần nào của hoạt động bắt đầu. Ví dụ cổ điển là một giao dịch cơ sở dữ liệu; Khi lưu hóa đơn, bao gồm tiêu đề và nhiều chi tiết đơn hàng, mọi phần của mỗi hàng cơ sở dữ liệu phải được đặt thành công; nếu không, dữ liệu bị mất hoặc bị hỏng. Nếu một mục hàng không thể được chèn, thì không chỉ không nên chèn các hàng khác mà còn không có hàng nào được xử lý.

An toàn luồng đề cập đến sự kết hợp của nhiều thứ, bao gồm cả nguyên tử, cho phép một hoạt động được "tái xuất"; nhiều công nhân có thể thực hiện cùng một hoạt động, bắt đầu từ cùng một thời điểm hoặc khác nhau, mà không ảnh hưởng đến bất kỳ công việc nào khác. Có nhiều mô hình cho hoạt động an toàn luồng; hầu hết trong số họ sôi sục về mặt khái niệm để chạy nhiều tác vụ song song trong sự cô lập hoàn toàn (hai công nhân có thể thực hiện cùng một nhiệm vụ trên hai đối tượng hoặc bộ sưu tập đối tượng khác nhau mà không hề biết công nhân kia thậm chí tồn tại) hoặc thiết lập một "đường ống" trong đó nhiều công nhân mỗi người thực hiện một nhiệm vụ trong toàn bộ hoạt động (mỗi công nhân tiến triển từ nhiệm vụ đầu tiên sang công việc tiếp theo, hoặc người khác tập trung vào một nhiệm vụ và giao "sản phẩm công việc" trung gian cho công nhân tiếp theo).


2

Một hoạt động nguyên tử là một hoạt động không thể bị gián đoạn.

Một chủ đề an toàn là một chủ đề có thể bị gián đoạn một cách an toàn.

An toàn luồng có được với các hoạt động nguyên tử, đặc biệt là trong logic ngăn chặn các tài nguyên quan trọng được truy cập nhiều lần.

Hoạt động nguyên tử cơ bản là Test-and-set , được sử dụng để thực hiện các semaphores, lần lượt được sử dụng để thực hiện an toàn luồng.


Một hoạt động gồm nhiều bước có thể bị gián đoạn và được gọi là nguyên tử hay không nếu nó được đảm bảo để khôi phục lại những thay đổi của nó?
user50849

1
Không. Nguyên tử phải được hiểu theo nghĩa từ nguyên của nó: nguyên tử, không thể chia cắt.
mouviciel

Là int, bool, float là chủ đề an toàn hay nguyên tử?
dùng960567

Nhưng không có sự khác biệt giữa việc không thể phân biệt và xuất hiện không thể chia sẻ với người quan sát ? Theo định nghĩa của bạn, không phải hoạt động nguyên tử có thể chứa nhiều hơn một bước. Tôi tin rằng từ "xuất hiện" trong định nghĩa hoạt động nguyên tử của wikipedia là quan trọng. (Tôi đang trò chuyện nếu có ai muốn đưa nó lên đó) :)
user50849

Có một sự khác biệt lớn: một chuỗi an toàn có thể bị gián đoạn và không có sự bảo đảm về thời gian. Điều này là rất quan trọng trong điện toán thời gian thực. Một hoạt động nguyên tử (với các khóa ngắt nếu nó là nhiều bước) được bảo đảm để chấm dứt sau một khoảng thời gian dự đoán.
mouviciel

1

An toàn luồng là nhiều hơn một khung hoặc một "khái niệm", hoạt động nguyên tử là một tập hợp con, một phương tiện (một trong nhiều) để đạt được trạng thái là được phân loại 'an toàn luồng'.

An toàn luồng đề cập đến một quá trình có thể được truy cập bởi các luồng riêng biệt, trong đó quyền truy cập của một (và thao tác dữ liệu), sẽ không làm hỏng tính toàn vẹn của hoạt động của các luồng khác.

Phần lớn kỹ năng của lập trình viên là biết cách đạt được điều này, tùy thuộc vào tình huống và mục tiêu chính, bạn có thể cần phải thực hiện, ví dụ: khóa, semaphores, chốt, đối tượng nguyên tử, quy tắc đồng bộ hóa, v.v ...

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.