Атомные свойства vs потокобезопасные в Objective-C

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

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

Итак, когда мы говорим, что он не будет возвращать мусор, будет ли мусор быть в том смысле, что если бы объект был неатомным, и объект пытался получить к нему доступ, а другой писал ему, он мог бы получить результат назад, писать и получать только частичную, неполную версию изменения, вызванного записью? Это то, что означает "мусор" в этом смысле, и какие атомарные свойства помогают предотвратить?

Ответ 1

An atomic свойство Objective C гарантирует, что вы никогда не увидите частичную запись. Когда a @property имеет атрибут atomic, невозможно только частично записать значение. Установщик такой:

- (void)setProp:(NSString *)newValue {
    [_prop lock];
    _prop = newValue;
    [_prop unlock];
}

Итак, если два потока хотят записать значение @ "test" и @ "otherTest" одновременно, тогда в любой момент времени свойство может быть только начальным значением свойства или @ "test" или @ "otherTest" . nonatomic выполняется быстрее, но значение представляет собой значение мусора и не содержит частичную строку @ "test" /@ "otherTest" (спасибо @Gavin) или любое другое значение мусора.

Но atomic только поточно-безопасный с простым использованием. Это не гарантировано. Appledoc сообщает следующее:

Рассмотрим объект XYZPerson, в котором оба человека первыми и последними имена изменяются с использованием атомарных аксессуаров из одного потока. Если другой поток обращается к обоим именам одновременно, методы атомарного геттера вернет полные строки (без сбоев), но theres no гарантировать, что эти значения будут правильными именами по отношению к каждому Другие. Если к моменту первого изменения доступа требуется первое имя, но последнее имя будет доступно после изменения, вы получите непоследовательность, несогласованная пара имен.

У меня никогда не было проблемы с использованием атома. Я разработал код таким образом, что нет проблем с атомными свойствами.

Ответ 2

В ответ на ваш третий абзац; в основном да. Номер атома не может быть прочитан, пока поток записывает номер.

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

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

Ответ 3

Роберт Харви ответил правильно, но есть подзаголовок, чтобы считать, что люди часто пропускают. Рассмотрим этот код: http://pastebin.com/S7XyJm6G

Кроме того, чтобы избежать чтения частично записанных значений, свойства атома также препятствуют возврату объектов, которые вы не контролируете на всю жизнь (они делают это, сохраняя и затем автореализовывая объект). Это важно в однопоточном коде, например, в примере, который я связал, но еще важнее в многопоточном коде, где другой поток может вызвать освобождение объекта из-под вас.

Ответ 4

В параллельном программировании:

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

non atomic означает, что если значение свойства, доступное для записи операции в некотором потоке (поток # 1) и другой поток (поток # 2), пытается получить доступ к неатомному значению либо для операции чтения или записи, а затем к другому потоку (поток # 2) получает значение сразу получает старое значение

Ответ 5

Явная реализация

@property (атомный, сохранение) NSNumber * count

будет таким образом

- (NSNumber *)count {
    NSNumber *count;
    @synchronized(self) {
        count = [_count retain]; // +1
    }
    return [count autorelease]; // delayed -1
}

- (void)setCount:(NSNumber *)count {
    id oldValue;
    @synchronized(self) {
        oldValue = _count;
        _count = [count retain];
    }
    [oldValue release];
}

Atomic - это поведение по умолчанию для свойства. Атомное свойство добавляет уровень безопасности потоков при получении или настройке значений. То есть, getter и setter для свойства всегда будут полностью завершены независимо от того, что делают другие потоки. эти свойства будут немного медленнее для доступа, чем неатомный эквивалент.

И явно мы будем реализовывать

@property (неатомный, сохранить) NSNumber * count

как это

- (NSNumber *)count {
    return _count;
}

- (void)setCount:(NSNumber *)count {
    if (count != _count) {
        id oldValue = _count;
        _count = [count retain];
        [_oldValue release];
    }
}

Неатомические свойства не являются потокобезопасными и будут возвращать их свойства напрямую. Это будет быстрее, чем атомные свойства, но, очевидно, несет определенный риск, если будут приняты меры предосторожности.

сеттер и геттер для этих неатомических свойств