2010-10-25 2 views
3

У меня есть простой класс, который выглядит немного как это:Запуск и остановка операций в поточно-образом

@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]; 
} 

Правильное ли решение? Не могли бы вы поступить иначе?

ответ

1

На каком языке это? Вы правы, первая версия не является потокобезопасной.

Синхронизированная версия является потокобезопасной. При явной блокировке вам нужно быть осторожным, чтобы не пропустить разблокировку на раннем пути возврата.

Если у вас есть доступ к заблокированным функциям xchg, вы можете сделать это довольно легко с помощью операции атомного обмена. cmpxchg также работает.

start() { 
    if (locked_xchg(running, YES) == YES) { 
     // the old value was YES, so nothing to do 
     return 
    } 
+0

Это Objective-C на iOS. Спасибо за подсказку 'locked_xchg', у меня есть' OSAtomicTestAndSet', который должен быть примерно таким же. – zoul

+0

Нет проблем. Это классическая ошибка, которую делают люди. К сожалению, наш продукт Jinx не работает на iphone. В противном случае я бы рекомендовал использовать его, чтобы помочь поймать эти гонки. –

Смежные вопросы