Справка по использованию OSSpinLock * для замены a while(true) {sleep(1);}
-
06-09-2019 - |
Вопрос
Я поддерживаю приложение carbon C ++ на OS X.В одном из объектов кода есть "блокировка вращения", которая выглядит следующим образом,
while ( mState != RELEASED )
{
sleep( 1 );
}
Существует обратный вызов обслуживания после рендеринга, который передается в AudioUnitAddRenderNotify(), который устанавливает MState этих различных объектов.
Я думал об использовании встроенного семейства функций OSSpinLock для замены этого (хотя бы потому, что они потокобезопасны, а приведенный выше код, похоже, таковым не является).
Будет ли это разумным эквивалентом?Должен ли я также добавить некоторую защиту от блокировок в поток обслуживания, который манипулирует MState этих объектов?
OSSpinLock spin_lock = OS_SPINLOCK_INIT;
if (!OSSpinLockTry(&spin_lock))
OSSpinLockLock(&spin_lock);
while (mState != RELEASED)
OSSpinLockTry(&spin_lock);
OSSpinLockUnlock(&spin_lock);
Решение
Не используйте spinlock - spinlocks тратят впустую циклы процессора, бесконечно зацикливаясь, пока не получат блокировку.Блокировки вращения следует использовать только в том случае, если время удержания блокировки будет очень коротким.
Лучшей альтернативой было бы использовать переменная условия, такие как те , которые доступны в p - потоки библиотека.Таким образом, ваш поток будет находиться в спящем режиме и не будет тратить впустую никаких циклов процессора до тех пор, пока не будет выполнено условие.Смотрите пример, приведенный по этой ссылке, чтобы узнать, как использовать переменные условия pthreads.