Запуск и остановка операций потокобезопасным способом - PullRequest
3 голосов
/ 25 октября 2010

У меня есть простой класс, который выглядит примерно так:

@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 Ответ

1 голос
/ 25 октября 2010

Какой это язык?Вы правы, первая версия не является поточно-ориентированной.

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

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

start() {
    if (locked_xchg(running, YES) == YES) {
        // the old value was YES, so nothing to do
        return
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...