Mam klasy object-c z niektórymi metodami, które używają kolejki GCD, aby zapewnić równoległy dostęp do zasobu odbywa się serialnie (standardowy sposób to zrobić).Jak zaimplementować mechanizm blokowania z ponownym przypisywaniem w obiekcie-c poprzez GCD?
Niektóre z tych metod wymagają wywoływania innych metod tej samej klasy. Tak więc mechanizm blokujący musi być ponownie wprowadzony. Czy istnieje standardowy sposób, aby to zrobić?
Początkowo miałem każda z tych metod użyć
dispatch_sync(my_queue, ^{
// Critical section
});
zsynchronizować dostępy. Jak wiecie, gdy jedna z tych metod wywoła inną taką metodę, pojawia się zakleszczenie, ponieważ wywołanie dispatch_sync zatrzymuje bieżące wykonywanie, dopóki ten drugi blok nie zostanie wykonany, co nie może być również wykonane, ponieważ wykonanie w kolejce jest zatrzymane. Aby rozwiązać ten problem, użyłem np. Ta metoda:
- (void) executeOnQueueSync:(dispatch_queue_t)queue : (void (^)(void))theBlock {
if (dispatch_get_current_queue() == queue) {
theBlock();
} else {
dispatch_sync(queue, theBlock);
}
}
I w każdym z moich metod, używam
[self executeOnQueueSync:my_queue : ^{
// Critical section
}];
Nie lubię tego rozwiązania, ponieważ dla każdego bloku z innym typem powrotu, muszę napisać inną metodę. Ponadto problem ten wydaje mi się bardzo powszechny i uważam, że powinno istnieć lepsze, standardowe rozwiązanie tego problemu.
Czy zamiast tego użyłeś opcji '@ synchronized'? –
@MartinR, tak, ale '@ synchronized' jest klasycznym blokadą, nie opartym na GCD/kolejkach, i dlatego, jak rozumiem, nie należy go używać ze względu na prostotę i wydajność kodu. Tytuł tego pytania jest zatem mylący, ponieważ zawiera "blokadę". Chodzi mi o synchronizowanie dostępu w sposób bezpośredni z GDC/kolejkami. Po prostu nie miałem lepszych słów niż "blokowanie ponownego wejścia", ponieważ jest to nazwa rozwiązania problemu, które większość ludzi zna. –
@MartinR Ponadto, '' zsynchronizowane' ma tę zaletę, że prowadzi do prostszego kodu dla reentranta - bez względu na to - (jak nazwać to najlepiej?). Mimo to blokujący mechanizm ma mniejszą wydajność niż mechanizm stojący za kolejkami GCD. –