реализовать время задержки в с - PullRequest
29 голосов
/ 14 октября 2010

Я не знаю точно, как сформулировать поиск для этого ... так что мне не повезло найти что-нибудь ..: S

Мне нужно ввести задержку в C.

например, я хочу кое-что сделать, затем подождать, скажем, 1 минуту, а затем продолжить работу.

Это имело смысл?Кто-нибудь может мне помочь?

Ответы [ 14 ]

37 голосов
/ 14 октября 2010

В стандарте C (C99) для этого можно использовать time(), например:

#include <time.h>
:
void waitFor (unsigned int secs) {
    unsigned int retTime = time(0) + secs;   // Get finishing time.
    while (time(0) < retTime);               // Loop until it arrives.
}

Кстати, это предполагает, что time() возвращает значение разрешения в 1 секунду.Я не думаю, что это предусмотрено стандартом, поэтому вам, возможно, придется подстроиться под него.


Чтобы уточнить, это - только способ, который мне известенсделать это с помощью ISO C99 (и вопрос помечен не более чем буквой «C», что обычно означает, что портативные решения желательны, хотя, конечно, могут быть предоставлены решения для конкретных поставщиков).

Любымиесли вы работаете на платформе, которая предоставляет более эффективный способ, используйте его. Как указывалось в нескольких комментариях, могут быть специфические проблемы с такой узкой петлей, что касается использования процессора и времени работы от батареи.

Любая приличная ОС с временным интервалом могла бы сбрасывать динамический приоритет задачи, которая постоянно использует свой полный временной интервал, но заряд батареи может быть более проблематичным.* ничего о деталях ОС в размещенной среде, и этот ответ предназначен только для ISO C и ISO C (поэтому не нужно использовать sleep, select, вызовы Win32 API или что-то вроде that).

И имейте в виду, что POSIX sleep может прерываться сигналами.Если вы собираетесь пойти по этому пути, вам нужно сделать что-то вроде:

int finishing = 0; // set finishing in signal handler 
                   // if you want to really stop.

void sleepWrapper (unsigned int secs) {
    unsigned int left = secs;
    while ((left > 0) && (!finishing)) // Don't continue if signal has
        left = sleep (left);           //   indicated exit needed.
}
16 голосов
/ 14 октября 2010

Вот как вы можете сделать это на большинстве настольных систем:

#ifdef _WIN32
    #include <windows.h>
#else
    #include <unistd.h>
#endif

void wait( int seconds )
{   // Pretty crossplatform, both ALL POSIX compliant systems AND Windows
    #ifdef _WIN32
        Sleep( 1000 * seconds );
    #else
        sleep( seconds );
    #endif
}

int
main( int argc, char **argv)
{
    int running = 3;
    while( running )
    {   // do something
        --running;
        wait( 3 );
    }
    return 0; // OK
}

Вот как вы можете сделать это на микрокомпьютере / процессоре без таймера:

int wait_loop0 = 10000;
int wait_loop1 = 6000;

// for microprocessor without timer, if it has a timer refer to vendor documentation and use it instead.
void
wait( int seconds )
{   // this function needs to be finetuned for the specific microprocessor
    int i, j, k;
    for(i = 0; i < seconds; i++)
    {
        for(j = 0; j < wait_loop0; j++)
        {
            for(k = 0; k < wait_loop1; k++)
            {   // waste function, volatile makes sure it is not being optimized out by compiler
                int volatile t = 120 * j * i + k;
                t = t + 5;
            }
        }
    }
}

int
main( int argc, char **argv)
{
    int running = 3;
    while( running )
    {   // do something
        --running;
        wait( 3 );
    }
    return 0; // OK
}

Переменные waitloop должны быть точно настроены, они работали довольно близко для моего компьютера, но частотная шкала делает его очень неточным для современной настольной системы; Так что не используйте его, если вы не знакомы с металлом и не занимаетесь этим.

9 голосов
/ 14 октября 2010
6 голосов
/ 29 июля 2013

Хотя во многих реализациях функция time возвращает текущее время в секундах , не гарантирует того, что каждая реализация сделает это (например, некоторыеможет возвращать миллисекунд вместо секунд ).Таким образом, более переносимым решением является использование функции difftime.

difftime гарантируется стандартом C для возврата разницы во времени в секунд между двумя time_t значениями.Таким образом, мы можем написать переносную функцию временной задержки, которая будет работать на всех совместимых реализациях C .

#include <time.h>

void delay(double dly){
    /* save start time */
    const time_t start = time(NULL);

    time_t current;
    do{
        /* get current time */
        time(&current);

        /* break loop when the requested number of seconds have elapsed */
    }while(difftime(current, start) < dly);
}

Одна оговорка с time и difftime Функция заключается в том, что стандарт C никогда не определяет гранулярность.Большинство реализаций имеют гранулярность одну секунду .Хотя это нормально для задержек длительностью несколько секунд , наша функция задержки может слишком долго ждать задержек менее одной секунды .

Существует портативная стандартная альтернатива C: функция clock.

Функция clock возвращает наилучшее приближение реализации к времени процессора, используемому программой с начала определяемой реализацией эпохи, связанной столько для вызова программы.Чтобы определить время в секундах, значение, возвращаемое функцией clock, следует разделить на значение макроса CLOCKS_PER_SEC.

Функциональное решение clock очень похоже на наше функциональное решение time:

#include <time.h>

void delay(double dly){
    /* save start clock tick */
    const clock_t start = clock();

    clock_t current;
    do{
        /* get current clock tick */
        current = clock();

        /* break loop when the requested number of seconds have elapsed */
    }while((double)(current-start)/CLOCKS_PER_SEC < dly);
}

В этом случае есть оговорка, аналогичная time и difftime: гранулярность clock функция оставлена ​​для реализации.Например, машины с 32-разрядными значениями для clock_t с разрешением в микросекунд могут закончить перенос значения, возвращенного clock через 2147 секунд (около 36 минут).

Таким образом, рассмотрите возможность использования time и difftime реализации функции задержки для задержек продолжительностью не менее одной секунды и реализацию clock для задержек продолжительностью менее одной секунды .

Последнее предупреждение: clock возвращает процессорное время вместо календарное время ;clock может не соответствовать фактическому прошедшему времени (например, если процесс спит).

3 голосов
/ 14 октября 2010

Для задержек до одной минуты, sleep() - хороший выбор.

Если когда-нибудь вы захотите сделать паузу с задержкой менее одной секунды, вы можете рассмотреть poll() с таймаутом.

Оба являются POSIX.

1 голос
/ 17 декабря 2018

В стандартной библиотеке C нет функций sleep(), но POSIX предоставляет несколько опций.

Функция POSIX sleep() (unistd.h) принимает аргумент unsigned int для количества секунд, которое требуется для сна. Хотя это не функция стандартной библиотеки, она широко доступна, и glibc поддерживает ее даже при компиляции с более строгими настройками, такими как --std=c11.

Функция POSIX nanosleep() (time.h) принимает два указателя на timespec структуры в качестве аргументов и обеспечивает более точный контроль длительности сна. Первый аргумент указывает продолжительность задержки. Если второй аргумент не является нулевым указателем, он содержит оставшееся время, если вызов прерывается обработчиком сигнала.

В программах, использующих функцию nanosleep(), для компиляции может потребоваться макрос макроса функции . Следующий пример кода не будет компилироваться в моей системе Linux без макроса тестирования функций, когда я использую типичный вызов компилятора gcc -std=c11 -Wall -Wextra -Wpedantic.

POSIX когда-то имел функцию usleep() (unistd.h), которая принимала аргумент useconds_t для указания продолжительности сна в микросекундах. Эта функция также требовала макроса функционального теста при использовании со строгими настройками компилятора. Увы, usleep() устарел с POSIX.1-2001 и больше не должен использоваться. Рекомендуется использовать nanosleep() сейчас вместо usleep().

#define _POSIX_C_SOURCE  199309L     // feature test macro for nanosleep()

#include <stdio.h>
#include <unistd.h>    // for sleep()
#include <time.h>      // for nanosleep()

int main(void)
{
    // use unsigned sleep(unsigned seconds)
    puts("Wait 5 sec...");
    sleep(5);

    // use int nanosleep(const struct timespec *req, struct timespec *rem);
    puts("Wait 2.5 sec...");
    struct timespec ts = { .tv_sec = 2,          // seconds to wait
                           .tv_nsec = 5e8 };     // additional nanoseconds
    nanosleep(&ts, NULL);
    puts("Bye");

    return 0;
}
1 голос
/ 14 октября 2010

sleep(int) работает как хорошая задержка.На минуту:

//Doing some stuff...
sleep(60); //Freeze for A minute
//Continue doing stuff...
1 голос
/ 14 октября 2010

Попробуйте sleep(int number_of_seconds)

0 голосов
/ 28 мая 2019

// Предоставляет метод задержки ANSI C x миллисекунд

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

void delayMillis(unsigned long ms) {
    clock_t start_ticks = clock();
    unsigned long millis_ticks = CLOCKS_PER_SEC/1000;
    while (clock()-start_ticks < ms*millis_ticks) {
    }
}    

/* 
 * Example output:
 * 
 * CLOCKS_PER_SEC:[1000000]
 * 
 * Test Delay of 800 ms....
 * 
 * start[2054], end[802058], 
 * elapsedSec:[0.802058]
 */
int testDelayMillis() {

    printf("CLOCKS_PER_SEC:[%lu]\n\n", CLOCKS_PER_SEC);
    clock_t start_t, end_t;
    start_t = clock();
    printf("Test Delay of 800 ms....\n", CLOCKS_PER_SEC);
    delayMillis(800); 
    end_t = clock();
    double elapsedSec = end_t/(double)CLOCKS_PER_SEC;
    printf("\nstart[%lu], end[%lu], \nelapsedSec:[%f]\n", start_t, end_t, elapsedSec);

}

int main() {    
    testDelayMillis();
}
0 голосов
/ 06 ноября 2016

Напишите этот код:

void delay(int x)
{   int i=0,j=0;
    for(i=0;i<x;i++){for(j=0;j<200000;j++){}}
}

int main()
{
    int i,num;

    while(1) {

    delay(500);

    printf("Host name");
    printf("\n");}

}
...