Apple предоставляет некоторую документацию о синхронизации переменных и даже порядке выполнения. То, что я не вижу, - это документация о поведении кэша CPU. Какие гарантии и управление разработчику Objective-C необходимо обеспечить согласованность кеша между потоками?
Рассмотрим следующее, где переменная задана в фоновом потоке, но читается в основном потоке:
self.count = 0;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^ {
self.count = 5;
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"%i", self.count);
});
}
Должен ли считаться неустойчивым в этом случае?
Обновление 1
Документация в Inter-thread Communication гарантирует, что совместно используемые переменные могут использоваться для межпоточной связи.
Другим простым способом передачи информации между двумя потоками является использование глобальной переменной, общего объекта или общего блока памяти.
В этом случае это означает, что волатильность не требуется? Это противоречит документации в Барьеры памяти и изменчивые переменные:
Если переменная видима из другого потока, такая оптимизация может помешать другому потоку замечать какие-либо изменения. Применение ключевого слова volatile к переменной заставляет компилятор загружать эту переменную из памяти каждый раз, когда она используется.
Поэтому я до сих пор не знаю, требуется ли volatile, потому что компилятор может использовать оптимизацию кэширования регистров или если это не требуется, потому что компилятор каким-то образом знает что-то "общее".
В документации не очень понятно, что такое общая переменная или как компилятор знает об этом. В приведенном выше примере подсчитывается общий объект? Пусть говорят, что count - это int, тогда это не объект. Является ли это разделяемым блоком памяти или это относится только к объявленным переменным __block? Возможно, volatile требуется для неблокированных, необъектных, неглобальных, общих переменных.
Обновление 2
Для всех, кто думает, что это вопрос о синхронизации, это не так. Это касается поведения кэша процессора на платформе iOS.