Avatar ·

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

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

Современный способ: используйте std::this_thread::sleep_for

Начиная с C++11, в стандартной библиотеке появился мощный и переносимый механизм для работы с временем и потоками. Для паузы в миллисекундах лучшим решением будет функция std::this_thread::sleep_for из заголовочного файла <thread>. Этот способ работает на любой платформе, где есть компилятор с поддержкой C++11 (Linux, Windows, macOS и т.д.).

Вот как должен выглядеть ваш исправленный код:

#include <iostream>
#include <thread>   // для std::this_thread::sleep_for
#include <chrono>   // для std::chrono::milliseconds

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

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

  • std::chrono::milliseconds — это тип, представляющий длительность в миллисекундах. Вы можете указать любое целое число: 100, 1500 и т.д.
  • std::this_thread::sleep_for — функция, которая приостанавливает выполнение текущего потока на заданный промежуток времени.
  • Вам нужно подключить два заголовка: <thread> (для sleep_for) и <chrono> (для временных литералов и типов).

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

Библиотека <chrono> поддерживает и другие единицы:

// Секунды
std::this_thread::sleep_for(std::chrono::seconds(2));

// Микросекунды
std::this_thread::sleep_for(std::chrono::microseconds(5000));

// Наносекунды
std::this_thread::sleep_for(std::chrono::nanoseconds(1000000));

// Можно использовать литералы C++14 (если компилятор поддерживает)
using namespace std::chrono_literals;
std::this_thread::sleep_for(500ms);   // миллисекунды
std::this_thread::sleep_for(2s);      // секунды

Почему это лучше, чем старые функции?

  • Переносимость: код одинаково работает на Linux, Windows, macOS.
  • Типобезопасность: вы не перепутаете секунды с миллисекундами, как с sleep().
  • Современность: это часть стандарта C++, не нужно использовать устаревшие POSIX-функции (usleep, nanosleep).
  • Гибкость: легко менять единицы измерения или комбинировать (например, 500ms + 200ms).

Если вам нужен только Linux и старый код

Если по каким-то причинам вы не можете использовать C++11 (например, очень старый компилятор), то под Linux можно использовать usleep из <unistd.h>. Но это не рекомендуется, так как функция считается устаревшей и не переносится на Windows.

#include <unistd.h>
usleep(500000); // 500 миллисекунд = 500 000 микросекунд

В современных проектах всегда используйте std::this_thread::sleep_for — это самый правильный и безопасный путь.

<<>>

Альтернативный подход: nanosleep для точного контроля под Linux

Если вам нужна максимальная точность и вы работаете только под Linux, можно использовать функцию nanosleep из <time.h>. Она позволяет задать паузу с точностью до наносекунд и, в отличие от usleep, не считается устаревшей в POSIX. Однако этот способ не переносим на Windows.

Пример кода:

#include <iostream>
#include <time.h>   // для nanosleep

int main() {
    std::cout << "Старт..." << std::endl;
    
    struct timespec ts;
    ts.tv_sec = 0;          // секунды
    ts.tv_nsec = 500000000; // наносекунды (500 млн = 500 мс)
    
    nanosleep(&ts, nullptr);
    
    std::cout << "Прошло 500 мс!" << std::endl;
    return 0;
}

Важно: второй аргумент nanosleep (указатель на timespec) может содержать остаток времени, если пауза была прервана сигналом. Если это не критично, передавайте nullptr.

Несмотря на точность, я рекомендую в новых проектах всё же использовать std::this_thread::sleep_for из первого ответа — он проще, безопаснее и кроссплатформенный.