2012-10-07 25 views
13

Tôi là một lập trình viên có kinh nghiệm .NET và duỗi chân của mình bằng iOS. Một trong những cấu trúc đa luồng yêu thích của tôi trong .NET là ReaderWriterLock. Nó cho phép nhiều người đọc hoặc một người viết. Một trong những tính năng mà tôi thực sự thiếu trong iOS là các ổ khóa được tái tham gia. Tức là, reader threads can acquire the read lock multiple times miễn là chúng phát hành cùng một số lần. Tương tự như vậy, luồng ghi đơn lẻ có thể lấy khóa nhiều lần miễn là nó giải phóng khóa bằng một số tương đương.Cấu trúc khóa đọc/ghi lại entrant?

Tôi đã xem xét Khung iOS và không có cấu trúc nào xuất hiện để cung cấp cùng một hỗ trợ bao gồm cả ủy quyền lại. Tôi cũng nhìn vào thư viện pthread. Tôi tìm thấy rwlock, nhưng nó không cho phép tái nhập.

Có bất kỳ thứ gì trên iOS cho phép các ổ khóa đọc ghi lại không?

Trả lời

2

Từ iOS Threading Programming Guide:

Hệ thống hỗ trợ đọc-ghi ổ khóa chỉ sử dụng POSIX đề. Để biết thêm thông tin về cách sử dụng các khóa này, hãy xem trang người dùng pthread.

Vì vậy, tôi đoán nếu pthreads không hỗ trợ tái nhập, câu trả lời là không.

16

Có, chỉ thị @synchronized là reentrant. Xem Using the @synchronized Directive trong Hướng dẫn lập trình luồng và cũng có Threading bằng Ngôn ngữ lập trình ObjC.

Điều đó nói rằng, bạn hầu như không bao giờ nên sử dụng tính năng này trong iOS. Trong hầu hết các trường hợp, bạn có thể tránh các ổ khóa của tất cả các loại, hãy để một mình rất nặng (chậm) ổ khóa như ổ khóa reentrant. Xem Hướng dẫn lập trình đồng thời, và đặc biệt là phần Migrating Away from Threads, để biết thông tin mở rộng các phương pháp dựa trên hàng đợi mà iOS ưu tiên hơn việc quản lý và khóa luồng thủ công.

Ví dụ, khóa đọc/ghi các công trình như thế này sử dụng Grand Central Dispatch:

- (id)init { 
    ... 
    _someObjectQueue = dispatch_queue_create("com.myapp.someObject", 
              DISPATCH_QUEUE_CONCURRENT); 
} 

// In iOS 5 you need to release disptach_release(_someObjectQueue) in dealloc, 
// but not in iOS 6. 

- (id)someObject { 
    __block id result; 
    dispatch_sync(self.someObjectQueue, ^{ 
    result = _someObject; 
    }); 
    return result; 
} 

- (void)setSomeObject:(id)newValue { 
    dispatch_barrier_async(self.queue, ^{ 
    _someObject = newValue; 
}); 

Cách tiếp cận này cho phép người đọc song song không giới hạn, với nhà văn độc đáo, đồng thời đảm bảo rằng nhà văn không bao giờ bỏ đói và việc ghi và đọc được serialized, tất cả trong khi tránh bất kỳ cuộc gọi hạt nhân trừ khi có sự tranh chấp thực tế. Đó là tất cả để nói nó rất nhanh và đơn giản.

Khi trình đọc xuất hiện, bạn xếp hàng yêu cầu đọc giá trị và đợi yêu cầu xử lý. Khi một người viết đến, nó xếp hàng một yêu cầu rào cản để cập nhật nó, yêu cầu không có yêu cầu nào khác từ hàng đợi đó hiện đang chạy. Với cấu trúc này, nhà phát triển không cần quản lý bất kỳ khóa nào. Chỉ cần đặt mọi thứ vào hàng đợi theo thứ tự bạn muốn chúng chạy.

+0

'@ synchronized' là người tham gia lại nhưng không hỗ trợ nhiều người đọc. GCD sẽ yêu cầu tái cơ cấu đáng kể mã hiện tại của tôi. – Askable

+0

Bạn đúng là @synchronized không hỗ trợ nhiều người đọc. Cách tiếp cận này là không bình thường trong Cocoa, và tôi không quen thuộc với một giải pháp tuyệt vời cho nó vượt ra ngoài pthread_rwlock_init mà tôi nhớ là không reentrant. Loại khóa này, như tôi đã nói, là rất kém hiệu quả, và iOS và Mac hiện đại có cơ chế nhanh hơn, an toàn hơn và đơn giản hơn trong GCD và NSOperationQueue. Trong Mac cũ, đa nhiệm hợp tác (runloop) được ưu tiên mạnh mẽ. .NET thừa kế tình yêu của nó về các chủ đề và khóa từ Java. ObjC không khuyến khích luồng rõ ràng. Ca cao không giống như .NET và nó là giá trị học cách tiếp cận Cocoa trong iOS. –

+0

(Vâng; tôi biết điều này không thực sự trả lời câu hỏi của bạn. Xin lỗi về điều đó.) –

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