Подтвердить что ты не робот

Что является потокобезопасным атомарным или неатомным?

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

Предположим, что существует свойство атомной строки, называемое "имя", и если вы вызываете [self setName:@"A"] из потока A, вызовите [self setName:@"B"] из потока B и вызовите [self name] из потока C, тогда вся операция в другом потоке будет выполняться серийно, что означает, что если один поток выполняет setter или getter, тогда другие потоки будут ждать. Это делает свойство "имя" безопасным для чтения/записи, но если другой поток D вызывает [name release] одновременно, то эта операция может привести к сбою, поскольку здесь нет вызова setter/getter. Это означает, что объект безопасен для чтения/записи (ATOMIC), но не является потокобезопасным, так как другие потоки могут одновременно отправлять любые типы сообщений объекту.

Если свойство "name" было неатомным, то все потоки в приведенном выше примере - A, B, C и D будут выполняться одновременно с получением любого непредсказуемого результата. В случае атома, либо один из A, B или C будет выполняться первым, но D может выполняться параллельно.

Ваш комментарий к этому поможет нам....

И мой вопрос: ", который является потокобезопасным в cocoa, атомарном или неатомном?"

4b9b3361

Ответ 1

Для свойств ObjC - Ни поточно-безопасные.

Atomic более устойчив к ошибкам на резьбу. В целом, это любопытный дефолт. Сценариев, которые вы бы одобрили для атомных, очень мало. Atomic может увеличить вероятность правильности, но на слишком низком уровне можно считать заменой правильного механизма блокировки. Поэтому, если вам нужна безопасность потоков, вам по-прежнему нужен какой-то другой примитив синхронизации поверх атомных операций чтения/записи. Если вам не нужна безопасность потоков (например, экземпляр является неизменным или предназначен для запуска только из основного потока), атомный ничего не добавит.

Устойчивость к ошибкам на резьбу не является "качеством" - она ​​служит для маскировки реальных ошибок потоковой передачи и затрудняет их воспроизведение и обнаружение.

Также обратите внимание, что mutable vs. immutable типы фактически не гарантируют безопасность потоков. "Mutable" может использоваться в именах ObjC для ссылки только на интерфейс - внутренности неизменяемого экземпляра могут фактически иметь внутреннее изменяемое состояние. Короче говоря, вы не можете предположить, что тип, который имеет изменяемый подкласс, является потокобезопасным.


Вопрос:

Предположим, что существует свойство атомной строки, называемое "имя", и если вы вызываете [self setName: @ "A" ] из потока A, вызовите [self setName: @ "B" ] из потока B и вызовите [self name] из потока C, тогда вся операция в другом потоке будет выполняться серийно, что означает, что если один поток выполняет setter или getter, то другие потоки будут ждать.

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

если другой поток D вызывает [имя релиза] одновременно, то эта операция может привести к сбою, поскольку здесь не задействован вызов setter/getter.

Правильно.

Это означает, что объект безопасен для чтения/записи (ATOMIC), но не потокобезопасен, поскольку другие потоки могут одновременно отправлять сообщения любого типа в объект.

Ну, там действительно намного больше. Общий пример:

    @interface MONPerson : NSObject

    @property (copy) NSString * firstName;
    @property (copy) NSString * lastName;

    - (NSString *)fullName;

    @end

Атомный или неатомный вам понадобится механизм синхронизации (например, блокировка), если один поток читает из этого экземпляра, а другой пишет ему. У вас может быть одно MONPerson firstName и другое lastName - объект может быть изменен до того, как возвращаемое значение getter даже вернется к вам, или это может произойти:

Тема А:

p.firstName = @"Rob";

Тема B:

p.firstName = @"Robert";

Тема А:

label.string = p.firstName; // << uh, oh -- will be Robert

Если свойство "name" было неатомным, то все потоки в приведенном выше примере - A, B, C и D будут выполняться одновременно с созданием любого непредсказуемого результата.

Справа - начальные симптомы могут быть дисбалансами опорных счетчиков (утечка, перевыпуск).

В случае атома, либо один из A, B или C будет выполняться первым, но D может выполняться параллельно. Просьба прокомментировать это....

Правильно. Но если вы посмотрите на приведенный выше пример - атомный - редко подходящая замена блокировки. Вместо этого он должен выглядеть следующим образом:

Тема А:

[p lock]; // << wait for it… … … …
// Thread B now cannot access p
p.firstName = @"Rob";
NSString fullName = p.fullName;
[p unlock];
// Thread B can now access p
label.string = fullName;

Тема B:

[p lock]; // << wait for it… … … …
// Thread A now cannot access p
…
[p unlock];

Атомарные аксессоры могут в среднем более чем в двадцать раз медленнее, чем неатомные. Кроме того, если ваш класс должен быть потокобезопасным и иметь изменяемое состояние, вы, вероятно, закончите использование блокировки, когда он будет работать в параллельном сценарии. Правильная блокировка обеспечивает все необходимые вам гарантии - атомарные аксессоры в этом сценарии избыточны, использование атомистики только добавит процессорное время. Еще одна хорошая вещь о регулярном замке заключается в том, что у вас есть все необходимое для гранулярности - хотя оно часто тяжелее, чем блокировка спина, используемая для атомизации, вам обычно потребуется меньше приобретений, поэтому она заканчивается очень быстро, если вы правильно используете правильные блокировки.

Ответ 2

атом гарантирует атомный доступ к переменной, но не делает ваш поток кода безопасным. Также неатомный.

С помощью "atomic" синтезированные методы setter/getter гарантируют, что целое значение всегда возвращается из получателя или задается установщиком независимо от активности сеттера в любом другом потоке. Поэтому, если поток A находится в середине получателя, тогда как поток B вызывает сеттер, фактическое жизнеспособное значение будет возвращено вызывающему абоненту в A. Для неатомических у вас нет таких гарантий.

Ответ 3

atomic делает следующий поток безопасным.

self.myProperty = value;

или

id value = self.myProperty

он не делает следующий поток безопасным

[myPorperty addObject:value];

Atomic делает поток потокобезопасным для установки или получения свойства, но он не делает обращение к каким-либо методам этого свойства само по себе безопасным потоком.

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

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

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

Ответ 4

Там есть другое свойство "атома", которое не было упомянуто, что было необходимо для безопасности потока перед ARC (и, вероятно, все еще есть). Сначала объяснив, зачем это нужно: скажем без ARC, вы читаете свойство объекта и сразу сохраняете его. Но другой поток может войти только между вами, считывая свойство и вызов сохранения, установите для свойства object значение nil, в результате чего объект будет освобожден. Вы отправляете сохранение на освобожденный объект, что является нездоровым. И это было бы очень редкой ошибкой, потому что это происходит только тогда, когда время подходит. Чтобы этого избежать, свойства атомарного объекта всегда возвращают объекты с автореализацией.

Ответ 5

1) Оба не являются потоковыми. 2) Atomic - это только безопасный для чтения-записи. 3) Однако, если вы хотите создать потокобезопасность, вам нужно реализовать какой-либо механизм блокировки для потоковой передачи, например, блокировку блокировки мьютекса, блокировку блокировки. Прочитайте больше... https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/Multithreading/ThreadSafety/ThreadSafety.html

Ответ 6

Вам следует подумать о внедрении механизма блокировки, чтобы вы не зашли в тупик в своем приложении. Также, если вы используете базовые данные, вы должны прочитать информацию о безопасности потоков iOS.

См.

http://developer.apple.com/library/iOS/#documentation/Cocoa/Conceptual/Multithreading/ThreadSafetySummary/ThreadSafetySummary.html

http://developer.apple.com/library/iOS/#documentation/Cocoa/Conceptual/Multithreading/ThreadSafety/ThreadSafety.html%23//apple_ref/doc/uid/10000057i-CH8-SW1

Ответ 7

Не атомарный поток является потокобезопасным. Guranted получает значение переменной.