2013-09-06 47 views
6

Trong Android, tôi có thể truy cập và sửa đổi một cách an toàn các loại nguyên thủy từ các luồng khác nhau. Tôi đã sử dụng tính năng này để chia sẻ dữ liệu giữa vòng lặp vẽ OpenGL và cài đặt người dùng đã được sửa đổi trong giao diện người dùng Android chính của luồng. Bằng cách lưu trữ từng thiết lập trong một kiểu nguyên thủy và làm cho mỗi giá trị độc lập với nhau, nó an toàn để sửa đổi tất cả các biến này mà không cần sử dụng khóa hoặc từ khóa đồng bộ hóa.Liệu nguyên tử thực sự có ý nghĩa gì đối với nguyên thủy tổng hợp?

Điều này cũng đúng trong Mục tiêu-C? Tôi đọc rằng việc đặt nguyên tử trên một biến cơ bản làm cho bộ thu thập tổng hợp và setter sử dụng khóa, tương tự như sử dụng các phương thức đồng bộ trong Java. Và tôi đã đọc rằng lý do cho điều này là vì vậy một đối tượng không được sửa đổi một phần trong khi nó được đọc bởi một chủ đề khác.

Nhưng các kiểu nguyên thủy có an toàn không bị sửa đổi một phần, vì chúng có trong Java không? Nếu đúng như vậy, có vẻ như tôi có thể sử dụng cùng một mô hình cũ của tôi từ Java để chia sẻ dữ liệu giữa các luồng. Nhưng sau đó các từ khóa nguyên tử sẽ là vô nghĩa cho một nguyên thủy, chính xác?

Tôi cũng đọc rằng một giải pháp mạnh mẽ hơn và nhanh hơn việc sử dụng các biến nguyên tử là sao chép các đối tượng trước khi sử dụng chúng nếu chúng được truy cập từ nhiều luồng. Nhưng tôi không chắc làm thế nào điều đó có thể được thực hiện. Không thể một đối tượng nonatomic được sửa đổi trong khi nó đang trong quá trình được sao chép, do đó làm hỏng bản sao?

+1

tại sao không khai báo kiểu nguyên thủy với nguyên tử để đảm bảo an toàn luồng? – John

+0

bản sao có thể có của [Thuộc tính nguyên tử so với nonatomic] (http://stackoverflow.com/questions/588866/atomic-vs-nonatomic-properties) – bbum

+0

@ user1256663 Tôi đã nghe chúng rất chậm và tôi đang viết Ứng dụng OpenGL. Mối lo ngại về khung hình. – Tenfour04

Trả lời

6

loại nguyên thủy không đảm bảo được an toàn khỏi bị sửa đổi một phần vì sửa đổi các kiểu dữ liệu không đảm bảo được nguyên tử trong C và Objective-C kế thừa từ đó. C chỉ đảm bảo các điểm chuỗi liên quan và không có yêu cầu rằng việc xử lý giữa hai điểm thứ tự là nguyên tử - một nguyên tắc chung là mỗi biểu thức đầy đủ là một điểm chuỗi.

Trong thực tế, sửa đổi nguyên thủy thường là quy trình gồm hai bước; sửa đổi được thực hiện trong sổ đăng ký và sau đó được ghi vào bộ nhớ. Rất khó có khả năng bản thân nó sẽ không phải là nguyên tử nhưng cũng không có sự đảm bảo nào khi nó sẽ xảy ra so với sự sửa đổi. Ngay cả với chứng chỉ volatile, các đảm bảo duy nhất được cung cấp là về các điểm chuỗi.

Apple trưng ra một số hàm C cho hành động nguyên tử qua OSAtomic.h ánh xạ trực tiếp tới các hướng dẫn nguyên tử chuyên biệt mà CPU cung cấp để triển khai các cơ chế đồng thời. Có thể bạn có thể sử dụng một trong những thứ đó trực tiếp hơn là thông qua một mutex nặng tay.

mẫu thường gặp trong Objective-C là:

  • đối tượng bất biến và biến đổi chức năng - có những lý do quản lý bộ nhớ cũng nhưng đó là một phần lý do tại sao NSString, NSArray, vv, là đặc biệt rõ rệt từ NSMutableString, NSMutableArray, vv ;
  • hàng đợi công văn nối tiếp, có thể được kết hợp với sao chép-sửa đổi-thay thế bằng cách sao chép trên hàng đợi, đi đến một nơi khác để sửa đổi, sau đó nhảy trở lại hàng đợi để thay thế;
  • chẳng hạn @synchronized s, NSConditionLock hoặc các cơ chế đồng bộ hóa rõ ràng khác là phù hợp.

Chủ đề chính là hàng đợi công văn nối tiếp, đó là lý do tại sao bạn có thể bỏ qua vấn đề đồng thời hoàn toàn nếu bạn tự giới hạn mình.

-2

Tôi không tin rằng bạn có thể sửa đổi một phần một loại nguyên thủy, đó là một phần của những gì làm cho chúng nguyên thủy. Bạn có thể sửa đổi nó hoặc bạn không. Theo nghĩa đó, tôi sẽ nói rằng họ là chủ đề an toàn.

Bạn đúng khi bạn nói rằng từ khóa nguyên tử sẽ là vô nghĩa đối với loại nguyên thủy.

Có người đã mất một đâm vào này ở đây: Objective-c properties for primitive types

+1

Bạn không thể "xem" loại nguyên thủy được sửa đổi một phần * trên hầu hết các kiến ​​trúc *, miễn là nguyên thủy được liên kết bộ nhớ cache. –

+1

Phụ thuộc vào nguyên thủy và kiến ​​trúc. Ví dụ, một số kiến ​​trúc ARM sử dụng double-byte double nhưng chính thức chỉ hứa hẹn atomicity cho tải bốn byte và các cửa hàng. –

3

@properties tổng hợp nguyên tử được miễn dịch với các bản cập nhật một phần đồng thời. Các phương thức accessor sẽ sử dụng một khóa nếu cần thiết trên kiến ​​trúc đó.

Nói chung, các kiểu nguyên thủy trong C không nhất thiết phải an toàn đối với các bản cập nhật một phần đồng thời.

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