Что на самом деле делает delay(0)?
Я видел некоторый код, в котором разработчики добавляют задержку(0)
, это не имеет смысла, что он делает? Задержка с нулем миллисекунд, почему?
bool DFRobotDFPlayerMini::waitAvailable(unsigned long duration){
unsigned long timer = millis();
if (!duration) {
duration = _timeOutDuration;
}
while (!available()){
if (millis() - timer > duration) {
return false;
}
delay(0);
}
return true;
}
@Sigma, 👍5
1 ответ
Лучший ответ:
Задержка (традиционно) выполняет две функции:
- Подождите некоторое время
- Обработка результатов для других потоков с помощью
слабого символа yield ()
.
Используя задержку(0)
, автор думает, что они говорят: "Я не хочу здесь задерживаться, но если что-то использует функцию yield ()
, оно может работать сейчас".
Однако это неверно.
Код для функции delay()
в ядре AVR выглядит следующим образом:
void delay(unsigned long ms)
{
uint32_t start = micros();
while (ms > 0) {
yield();
while ( ms > 0 && (micros() - start) >= 1000) {
ms--;
start += 1000;
}
}
}
Вы можете видеть, что, как и задержка на определенный период, yield()
регулярно вызывается. Однако это происходит только в том случае, если мс
больше 0. Если вы передадите 0
в качестве длины задержки, то функция delay ()
, по сути, вообще ничего не делает.
Теперь может случиться так, что более ранняя версия ядра всегда вызывала функцию yield()
даже при ms==0
, но текущая версия этого не делает. Может быть, это зависание от старого стиля кодирования. Но для текущего ядра, если вы хотите получить результат, вы должны явно вызвать yield()
или задержку по крайней мере на одну миллисекунду.
- Случайная ошибка "Compilation error: Error: 13 INTERNAL: exit status 1". Как устранить или что вызывает эту ошибку
- Есть ли необходимость вводить задержку в основной цикл
- Использование задержки 1 мс () в цикле for для проверки входных данных.. Плохо?
- Как независимо запускать позиционные и непрерывные сервоприводы с помощью millis()?
- Функция Tone() ставит паузы между нотами
- Вопрос об использовании millis для сигнальных условий - Arduino
- Использование millis вместо задержки перезагрузки реле
- Помощь проектом слишком быстрого переключения реле водяного насоса.
esp8266
задержка
имеет выход с задержкой 0, а esp32 "задержка" напрямую вызывает vTaskDelay в SDK. Ядра mded вызывают спящий режим потока RTOS., @JurajЕсть ли что-нибудь, чему можно уступить *в ядре AVR?, @AndreKR
@AndreKR Не в ядре, нет. "yield ()" определяется как "слабый", чтобы вы (или библиотека) могли переопределить его для реализации формы грубой совместной потоковой передачи., @Majenko
Да, это именно то, что я видел, когда смотрел на метод delay (). Это еще больше сбивало с толку. Таким образом, он ничего не делает, так как миллисекунды меньше нуля., @Sigma
Не "ниже", а "не больше". Тонкая разница., @Majenko
@Majenko Извините =P, @Sigma