2010-02-14 2 views
7

Что происходит, когда два потока устанавливают BOOL на YES «в одно и то же время»?Является ли BOOL для чтения/записи атома в Objective C?

+16

Он открывает червоточину в другое измерение. – dreamlax

+5

Если они оба установить его в 'YES', не может быть проблемой может ли запись атомарной или нет, может ли там? –

+0

@CarlNorum, которая может быть правдой, но это не очевидно для меня, почему –

ответ

6

Номер без стопорной конструкции, чтение/запись любого переменного типа, не является атомарным в Objective C.

Если два потока написать ДА в то же время к BOOL, результат ДА независимо от того, какой из них получает во-первых.

Пожалуйста, см: Synchronizing Thread Execution

+2

Спасибо, Митч. ead устанавливает его в YES, а другой устанавливает значение NO, может ли быть повреждение памяти? – Jacko

+1

http://developer.apple.com/mac/library/DOCUMENTATION/Cocoa/Conceptual/Multithreading/ThreadSafety/ThreadSafety.html дает очень подробное обсуждение. Я думаю, что я буду использовать int вместо BOOL и использовать операции OSAtomic для этого int. – Jacko

+0

Вмешательство в ваш вопрос заключается в том, может ли хруст какой-либо другой фрагмент памяти. Нет; этого не может быть. Самое худшее, что произойдет, вы прочитаете NO, похоже, после того, как вы написали ДА в другом потоке. – bbum

7

Вот код для решения предложенного Jacko.
Использование volatileuint32_t с OSAtomicOr32Barrier и OSAtomicAnd32Barrier

#import <libkern/OSAtomic.h> 

volatile uint32_t _IsRunning; 

- (BOOL)isRunning { 
    return _IsRunning != 0; 
} 

- (void)setIsRunning:(BOOL)allowed { 

    if (allowed) { 
     OSAtomicOr32Barrier(1, & _IsRunning); //Atomic bitwise OR of two 32-bit values with barrier 
    } else { 
     OSAtomicAnd32Barrier(0, & _IsRunning); //Atomic bitwise AND of two 32-bit values with barrier. 
    } 
} 
+0

Прохладный! Но почему бы просто не использовать 'OSAtomicOr32Barrier (allowed, & _IsRunning);' вместо условного оператора? –

+0

Да, вы можете использовать. –

+0

А, это не так просто, извините. Вы не можете использовать «или» версию для сброса флага, т. Е. Для этого вы должны использовать «и» версию (OSAtomicAnd32Barrier). –

3

Я бы отклоняться от принятого ответа. Сожалею. Хотя объектив c не гарантирует, что свойства BOOL, объявленные как неатомные , на самом деле атомарны, я должен угадать, что аппаратное обеспечение, которое вы больше всего заботитесь (все устройства iOS и macos), имеет инструкции для выполнения байтов, считывающих и хранящих атомарно. Итак, если Apple не выйдет с ОС Road Light, работающей на микроконтроллере IBM, который имеет шину шириной 5 бит для отправки 10-битных байтов по сравнению с , вы могли бы также использовать неатомные BOOL в ситуации, которая требует атомных BOOL. Код не был бы переносимым для Road Light OS, но если вы можете жертвовать будущей безопасностью вашего кода, неатомный, это нормально для этого варианта использования. Я уверен, что есть ожесточенные люди на s.o. что поднимет задачу демонтажа синтезированного приемника BOOL и сеттера для атомных/неатомических случаев, чтобы узнать, в чем разница. По крайней мере, на ARM.

Ваш вынос из этого, скорее всего, это

  1. вы можете объявить свойства BOOL как атомная и это не будет стоить вам ни копейки на всех HW прошивкой и MacOS внутренне поддерживает.
  2. барьеры памяти ортогональны атомарность
  3. вы определенно не должны использовать 4 свойство байт для хранения Булевых в , если вы не в [самой] нечеткую логику. Это идиотский и расточительный, вы не хотите быть клоном Java-программиста, , который не может сказать поплавок из двойника, или вы?
  4. BOOL переменные (которые не очевидно, поддерживают атомные/неатомические декоратор не будет атомными на некоторых узких шинные архитектурах цели C бы не использовать в любом случае (микроконтроллеры с или без некоторого [самого] микро OS являются C & сборки территории Я полагаю, что они обычно не нуждаются в багаже ​​ ObjC выполнения принесет)
Смежные вопросы