Avatar ·

Как сделать паузу (задержку) в C++ на определенное количество миллисекунд?

Привет! Я пишу простую консольную программу на C++ под Linux. Мне нужно, чтобы программа делала паузу на несколько миллисекунд (например, 500 мс) между выводами текста или выполнением каких-то действий. Я новичок, и пока что пробовал просто `sleep(1)` из ``, но это работает только для секунд. А мне нужна задержка в миллисекундах. Я слышал, что есть `usleep()`, но в некоторых источниках пишут, что он устарел, да и непонятно, как правильно его использовать. Вот пример моего кода, который не работает так, как я хочу: ```cpp #include #include int main() { std::cout << "Начало..." << std::endl; sleep(0.5); // Хочу 500 мс, но sleep принимает только целые секунды std::cout << "Прошло 500 мс?" << std::endl; return 0; } ``` Очевидно, что `sleep(0.5)` не сработает, так как аргумент должен быть целым числом. Подскажите, пожалуйста, как правильно сделать задержку в C++ на миллисекунды? Желательно с примером кода. Заранее спасибо! <<>>

Использование std::this_thread::sleep_for (C++11 и новее)

Современный и предпочтительный способ — использовать стандартную библиотеку потоков, доступную начиная с C++11. Функция std::this_thread::sleep_for принимает длительность в виде объекта std::chrono::duration. Это кроссплатформенное решение (работает на Linux, Windows, macOS).

#include <iostream>
#include <thread>
#include <chrono>

int main() {
    std::cout << "Начало..." << std::endl;
    
    // Задержка на 500 миллисекунд
    std::this_thread::sleep_for(std::chrono::milliseconds(500));
    
    std::cout << "Прошло 500 мс!" << std::endl;
    return 0;
}

Для компиляции добавьте флаг -pthread (на Linux): g++ -std=c++11 -pthread program.cpp -o program.

Как это работает

  • std::chrono::milliseconds(500) — создает объект длительности, равный 500 мс.
  • std::this_thread::sleep_for — приостанавливает выполнение текущего потока на указанное время.
  • Точность зависит от операционной системы и планировщика, но обычно составляет 1–10 мс.

Другие единицы времени

Вы можете использовать любые единицы из <chrono>:

  • std::chrono::seconds(2) — 2 секунды.
  • std::chrono::microseconds(1000) — 1000 микросекунд (1 мс).
  • std::chrono::nanoseconds(500000000) — 500 млн наносекунд (500 мс).

Или комбинировать: std::chrono::milliseconds(1500) = 1.5 секунды.

Альтернативы для старых стандартов (C++98/C++03)

Если вы вынуждены использовать старый компилятор, можно применить usleep() из POSIX (Linux/Unix):

#include <unistd.h> // для usleep

int main() {
    usleep(500000); // 500 000 микросекунд = 500 мс
    return 0;
}

Недостатки: usleep() устарел в POSIX.1-2001 и удален из POSIX.1-2008. Лучше использовать nanosleep():

#include <time.h>

int main() {
    struct timespec ts;
    ts.tv_sec = 0;          // секунды
    ts.tv_nsec = 500000000; // наносекунды (500 мс)
    nanosleep(&ts, NULL);
    return 0;
}

Но современный C++11 решает эту проблему элегантно и кроссплатформенно.

Почему не стоит использовать sleep() с дробным числом?

Функция sleep() ожидает целое число секунд типа unsigned int. Передача 0.5 неявно преобразуется в 0, и задержки не будет. Это распространенная ошибка новичков.

<<>>

Использование nanosleep() для точных задержек

Если вам нужна максимальная точность (например, для эмуляции реального времени или работы с сенсорами), используйте POSIX-функцию nanosleep(). Она позволяет задавать задержку с точностью до наносекунд (на практике — до микросекунд).

#include <time.h>
#include <iostream>

int main() {
    struct timespec req, rem;
    req.tv_sec = 0;
    req.tv_nsec = 500000000; // 500 мс = 500 000 000 нс
    
    // nanosleep может быть прерван сигналом, тогда в rem будет остаток времени
    while (nanosleep(&req, &rem) == -1) {
        if (errno == EINTR) {
            // Если прервано сигналом, продолжаем спать оставшееся время
            req = rem;
        } else {
            // Другая ошибка
            std::cerr << "Ошибка nanosleep" << std::endl;
            return 1;
        }
    }
    std::cout << "Задержка завершена!" << std::endl;
    return 0;
}

Преимущества:

  • Высокая точность (наносекунды).
  • Не требует C++11 и дополнительных флагов компиляции (кроме стандартных).
  • Обрабатывает прерывания сигналами (цикл while).

Недостатки:

  • Работает только на POSIX-системах (Linux, macOS, BSD). Для Windows нужно другое решение.
  • Код сложнее, чем sleep_for.

Если вы пишете кроссплатформенное приложение, используйте std::this_thread::sleep_for из первого ответа. Если только под Linux и нужна точность — nanosleep() отличный выбор.