iPhone: Как я могу реализовать семафор? - PullRequest
2 голосов
/ 04 октября 2011

Может кто-нибудь объяснить, как я могу реализовать семафор в Objective-C? Я провел много поисков в Google по этой теме, но ничего не понял.

Ответы [ 4 ]

12 голосов
/ 04 октября 2011

Если вам определенно нужен фактический семафор, вероятно, лучше всего использовать семафоры диспетчеризации GCD .Я бы добавил объяснение, но код в ссылке довольно прост.Вы должны быть в состоянии следовать за этим.

По сути, вы создаете семафор с параметром, который указывает количество одновременных экземпляров вашего ресурса, которые вы можете иметь.Затем потоки, которые хотят использовать ресурс, ждут семафор, пока один из них не станет доступным, и сообщат об этом, когда они будут сделаны.

Рассмотрите возможность использования очереди отправки или NSOperationQueue вместо этого с одновременным ограничением количества экземпляров вашего ресурса.Это одобренный Apple способ делать такие вещи.

3 голосов
/ 04 октября 2011

C apis можно найти в sys/semaphore.h.используйте их в вашей оболочке / реализации objc.

этот базовый пример является первым результатом, когда 'sem_trywait example' гуглится.он показывает вам, как вы можете использовать эти apis.

, тогда минимальный интерфейс примет такую ​​форму:

@interface MONSemaphore : NSObject
{
    sem_t semaphore;
}

- (int)close;
- (int)destroy;

/* .. and the rest of the interface you wrap and make public here .. */

@end

, но, вероятно, вы также захотите, чтобы объект абстрагировал init и destructподпрограммы от клиента.

2 голосов
/ 04 октября 2011

Вам следует использовать NSLock или NSCondition , если вы хотите самостоятельно обрабатывать защиту данных и критический раздел. Вы также можете использовать @ синхронизированную директиву . Вы также можете просто использовать обычный API-интерфейс потока POSIX, если вам это нравится, хотя это не рекомендуется, поскольку Cocoa дает вам множество вещей более высокого уровня, которые проще и приятнее. Это обсуждение было мне полезно.

2 голосов
/ 04 октября 2011

С Apple Docs (Threading) :

Objective-C поддерживает многопоточность в приложениях. Таким образом, два потока могут пытаться изменить один и тот же объект одновременно, что может вызвать серьезные проблемы в программе. Чтобы защитить разделы кода от одновременного выполнения несколькими потоками, Objective-C предоставляет директиву @synchronized ().

Директива @synchronized () блокирует часть кода для использования одним потоком. Другие потоки блокируются до тех пор, пока поток не выйдет из защищенного кода, то есть когда выполнение продолжится после последнего оператора в блоке @synchronized ().

Директива @synchronized () принимает в качестве единственного аргумента любой объект Objective-C, включая self. Этот объект известен как семафор взаимного исключения или мьютекс. Это позволяет потоку заблокировать часть кода, чтобы предотвратить его использование другими потоками. Вы должны использовать отдельные семафоры для защиты различных критических разделов программы. Прежде чем приложение станет многопоточным, безопаснее всего создавать все объекты взаимного исключения, чтобы избежать условий гонки.

Пример:

Account *account = [Account accountFromString:[accountField stringValue]];

// Get the semaphore.
id accountSemaphore = [Account semaphore];

@synchronized(accountSemaphore) {
    // Critical code.
    ...
}
...