У меня есть простой класс, который выглядит немного как это:Запуск и остановка операций в поточно-образом
@protocol Recorder
@property(BOOL) isRunning;
- (void) start;
- (void) stop;
@end
И реализации метода:
- (void) start {
if (running)
return;
…
running = YES;
}
- (void) stop {
if (!running)
return;
…
running = NO;
}
И я начал думать о теме безопасность. Нынешнее решение не является потокобезопасным, не так ли? Как об этом:
- (void) start {
@synchronized(self) {
if (running)
return;
…
running = YES;
}
}
Является ли это правильно, при условии, что метод -stop
также синхронизируется? Мне не нравится дополнительное гнездование, введенное @synchronized
. Будет ли явная блокировка работать?
- (void) stop {
[startStopLock lock];
if (running)
return;
…
running = YES;
[startStopLock unlock];
}
Или я мог бы это сделать?
enum { Running, Stopped };
NSConditionLock *startStopLock;
- (void) start {
if (![startStopLock tryLockWithCondition:Stopped])
return;
…
[startStopLock unlockWithCondition:Running];
}
Правильное ли решение? Не могли бы вы поступить иначе?
Это Objective-C на iOS. Спасибо за подсказку 'locked_xchg', у меня есть' OSAtomicTestAndSet', который должен быть примерно таким же. – zoul
Нет проблем. Это классическая ошибка, которую делают люди. К сожалению, наш продукт Jinx не работает на iphone. В противном случае я бы рекомендовал использовать его, чтобы помочь поймать эти гонки. –