Изменение, которое упомянул модификатор доступа
counter
кpublic volatile
Как другие люди, это самостоятельно не на самом деле безопасно вообще. Точка volatile
- то, что несколько потоков, работающих на нескольких центральных процессорах, могут и быть данные кэша и переупорядочивать инструкции.
, Если это не volatile
, и ЦП инкременты значение, затем ЦП B не может на самом деле видеть, что увеличенное значение до некоторое время спустя, который может вызвать проблемы.
, Если это volatile
, это просто гарантирует, чтобы эти два центральных процессора видели те же данные одновременно. Это не останавливает их вообще от чередования их чтений и операций записи, который является проблемой, которой Вы стараетесь избегать.
lock(this.locker) this.counter++
;
Это безопасно сделать (если Вы еще помните к lock
везде, что Вы получаете доступ this.counter
). Это препятствует тому, чтобы любые другие потоки выполнили любой другой код, который охраняют locker
. Используя блокировки также, предотвращает проблемы переупорядочения мульти-ЦП как выше, который является большим.
проблема, блокировка является медленной, и если Вы снова используете locker
в некотором другом месте, которое действительно не связано тогда, можно закончить тем, что блокировали другие потоки ни по какой причине.
Interlocked.Increment(ref this.counter);
Это безопасно, поскольку это эффективно делает чтение, инкремент, и пишет в 'одном хите', который не может быть прерван. Из-за этого это не будет влиять ни на какой другой код, и Вы не должны помнить блокировать в другом месте также. Это также очень быстро (как MSDN заявляет на современных центральных процессорах, это - часто буквально единственная инструкция по ЦП).
я не совсем уверен однако, если он обходит другие центральные процессоры, переупорядочивающие вещи, или если также необходимо объединиться энергозависимый с инкрементом.
InterlockedNotes:
Как [1 111] не предотвращает эти виды проблем многопоточности, для чего это? Хороший пример говорит, что у Вас есть два потока, тот, который всегда пишет в переменную (говорят queueLength
), и тот, который всегда читает из той же самой переменной.
, Если queueLength
не энергозависимо, поток A может записать пять раз, но распараллелить B, может видеть те записи, как откладываемые (или даже потенциально в неправильном порядке).
решение для А состояло бы в том, чтобы заблокировать, но Вы могли также использовать энергозависимый в этой ситуации. Это гарантировало бы, что поток B будет всегда видеть самую актуальную вещь, которые распараллеливают A, записал. Обратите внимание однако, что эта логика [только 1 117] работы, если у Вас есть писатели, которые никогда не читали, и читатели, которые никогда не пишут, и , если вещь Вы пишете, являются атомарным значением. Как только Вы делаете единственный read-modify-write, необходимо перейти к Взаимно блокируемым операциям или использовать Блокировку.
Поскольку каждый вызов делегата включает показатель точности, просто возвращайтесь из метода, пока не будет достигнута желаемая точность (предупреждение: этого может никогда не случиться).
Вы не можете просто перейти к десятиметровый результат - не зря его называют «желаемой», а не обязательной точностью. Вы должны дать время, чтобы вычислить более точные позиции.
Одна из стратегий - запустить таймер на период, достаточный для получить исправление (которое также будет приемлемо для пользователя)
+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)seconds target:(id)target selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)repeats
Запустить диспетчер местоположения, доставляющий обновления. Когда таймер истечет (или вы получите приемлемую точность), остановите обновления и используйте это местоположение.
Вероятно, это лучшее, что вы собираетесь получить. Вы можете предоставить пользователю возможность повторить попытку определения местоположения, если оно все еще недостаточно точное.