Что на самом деле делает delay(0)?

delay

Я видел некоторый код, в котором разработчики добавляют задержку(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;
}

, 👍5


1 ответ


Лучший ответ:

10

Задержка (традиционно) выполняет две функции:

  1. Подождите некоторое время
  2. Обработка результатов для других потоков с помощью слабого символа 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() или задержку по крайней мере на одну миллисекунду.

,

esp8266 задержка имеет выход с задержкой 0, а esp32 "задержка" напрямую вызывает vTaskDelay в SDK. Ядра mded вызывают спящий режим потока RTOS., @Juraj

Есть ли что-нибудь, чему можно уступить *в ядре AVR?, @AndreKR

@AndreKR Не в ядре, нет. "yield ()" определяется как "слабый", чтобы вы (или библиотека) могли переопределить его для реализации формы грубой совместной потоковой передачи., @Majenko

Да, это именно то, что я видел, когда смотрел на метод delay (). Это еще больше сбивало с толку. Таким образом, он ничего не делает, так как миллисекунды меньше нуля., @Sigma

Не "ниже", а "не больше". Тонкая разница., @Majenko

@Majenko Извините =P, @Sigma