Tôi có một lớp khách quan-c với một số phương thức, sử dụng hàng đợi GCD để đảm bảo rằng việc truy cập đồng thời vào một tài nguyên diễn ra theo cách serially (cách tiêu chuẩn để thực hiện điều này).Làm thế nào để thực hiện một cơ chế khóa reentrant trong mục tiêu-c thông qua GCD?
Một số phương pháp này cần gọi các phương thức khác của cùng một lớp. Vì vậy, cơ chế khóa cần phải được tái nhập cảnh. Có cách nào tiêu chuẩn để làm điều này không?
Lúc đầu, tôi đã từng trong những phương pháp sử dụng
dispatch_sync(my_queue, ^{
// Critical section
});
để đồng bộ hóa các truy cập. Như bạn đã biết, khi một trong các phương thức này gọi một phương thức như vậy, một bế tắc xảy ra bởi vì lệnh dispatch_sync dừng thực hiện hiện tại cho đến khi khối khác được thực thi, cũng không thể thực thi được, vì việc thực hiện trên hàng đợi bị dừng. Để giải quyết điều này, tôi đã sử dụng ví dụ: phương pháp này:
- (void) executeOnQueueSync:(dispatch_queue_t)queue : (void (^)(void))theBlock {
if (dispatch_get_current_queue() == queue) {
theBlock();
} else {
dispatch_sync(queue, theBlock);
}
}
Và trong mỗi phương pháp của tôi, tôi sử dụng
[self executeOnQueueSync:my_queue : ^{
// Critical section
}];
Tôi không thích giải pháp này, bởi vì đối với mỗi khối với một kiểu trả về khác nhau, tôi cần phải viết phương pháp khác. Hơn nữa, vấn đề này có vẻ rất phổ biến với tôi và tôi nghĩ rằng nên tồn tại một giải pháp tốt hơn, tiêu chuẩn cho việc này.
Bạn có cân nhắc sử dụng '@ synchronized' để thay thế không? –
@MartinR, vâng, nhưng '@ synchronized' là một khóa cổ điển, không dựa trên GCD/hàng đợi, và do đó, như tôi đã hiểu, nó không được khuyến khích sử dụng vì lý do đơn giản và hiệu suất mã. Tiêu đề của câu hỏi này là do đó gây hiểu lầm, bởi vì nó chứa "khóa". Những gì tôi có nghĩa là đồng bộ hóa truy cập một cách reentrant với GDC/hàng đợi. Tôi đơn giản không có lời nào tốt hơn là nói "khóa reentrant", bởi vì đó là tên của giải pháp cho vấn đề mà hầu hết mọi người đều biết. –
@MartinR, hơn nữa mặc dù '@ synchronized' có lợi thế là dẫn đến mã đơn giản hơn cho reentrant -whatever- (cách gọi này là tốt nhất?). Tuy nhiên, cơ chế khóa đằng sau nó có hiệu suất kém hơn so với cơ chế đằng sau hàng đợi GCD. –