Атомные свойства 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];
}
}
Неатомические свойства не являются потокобезопасными и будут возвращать их свойства напрямую. Это будет быстрее, чем атомные свойства, но, очевидно, несет определенный риск, если будут приняты меры предосторожности.
сеттер и геттер для этих неатомических свойств