C语言 在 c 中实现时间延迟

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3930363/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 06:42:05  来源:igfitidea点击:

implement time delay in c

ctimesleepdelaytimedelay

提问by developer

I don't know exactly how to word a search for this.. so I haven't had any luck finding anything.. :S

我不知道如何准确地搜索这个......所以我没有运气找到任何东西......:S

I need to implement a time delay in C.

我需要在 C 中实现时间延迟。

for example I want to do some stuff, then wait say 1 minute, then continue on doing stuff.

例如我想做一些事情,然后等一分钟,然后继续做事情。

Did that make sense? Can anyone help me out?

这样做有意义吗?谁能帮我吗?

回答by paxdiablo

In standard C (C99), you can use time()to do this, something like:

在标准 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.
}

By the way, this assumes time()returns a 1-second resolution value. I don't think that's mandated by the standard so you may have to adjust for it.

顺便说一下,这假设time()返回一个 1 秒的分辨率值。我不认为这是标准强制要求的,因此您可能需要对其进行调整。



In order to clarify, this is the onlyway I'm aware of to do this with ISO C99 (and the question is tagged with nothing more than "C" which usually means portable solutions are desirable although, of course, vendor-specific solutions may still be given).

为了澄清起见,这是我所知道的使用 ISO C99 执行此操作的唯一方法(并且问题仅标记为“C”,这通常意味着可移植解决方案是可取的,当然,供应商特定的解决方案仍然可以给出)。

By all means, if you're on a platform that provides a more efficient way, use it.As several comments have indicated, there may be specific problems with a tight loop like this, with regard to CPU usage and battery life.

无论如何,如果您在一个提供更有效方式的平台上,请使用它。正如一些评论所指出的,像这样的紧密循环可能存在特定问题,涉及 CPU 使用率和电池寿命。

Any decent time-slicing OS would be able to drop the dynamic priority of a task that continuously uses its full time slice but the battery power may be more problematic.

任何体面的时间片操作系统都能够降低连续使用其完整时间片的任务的动态优先级,但电池电量可能更成问题。

However C specifies nothingabout the OS details in a hosted environment, and this answer is for ISO C and ISO C alone (so no use of sleep, select, Win32 API calls or anything like that).

然而,C没有指定托管环境中的操作系统详细信息,这个答案仅适用于 ISO C 和 ISO C(因此不使用sleep, select, Win32 API 调用或类似的东西)。

And keep in mind that POSIX sleepcan be interrupted by signals. If you aregoing to go down that path, you need to do something like:

请记住,POSIXsleep可以被信号中断。如果你打算走这条路,你需要做的是这样的:

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.
}

回答by Frank

Here is how you can do it on most desktop systems:

以下是在大多数桌面系统上执行此操作的方法:

#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
}

Here is how you can do it on a microcomputer / processor w/o timer:

以下是在没有计时器的微型计算机/处理器上执行此操作的方法:

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
}

The waitloop variables must be fine tuned, those did work pretty close for my computer, but the frequency scale thing makes it very imprecise for a modern desktop system; So don't use there unless you're bare to the metal and not doing such stuff.

必须微调等待循环变量,这些变量在我的计算机上工作得非常接近,但是频率标度使得它对于现代桌面系统非常不精确;所以不要在那里使用,除非你对金属裸露并且不做这样的事情。

回答by Vilhelm Gray

Although many implementations have the timefunction return the current time in seconds, there is no guaranteethat every implementation will do so (e.g. some may return millisecondsrather than seconds). As such, a more portable solution is to use the difftimefunction.

尽管许多实现都有time函数以秒为单位返回当前时间,但不能保证每个实现都会这样做(例如,有些可能返回毫秒而不是)。因此,更便携的解决方案是使用该difftime功能。

difftimeis guaranteed by the C standardto return the difference in time in secondsbetween two time_tvalues. As such we can write a portable time delay function which will run on all compliant implementations of the C standard.

difftimeC 标准保证返回两个值之间的时间差(以秒为单位)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);
}


One caveat with the timeand difftimefunctions is that the C standardnever specifies a granularity. Most implementations have a granularity of one second. While this is all right for delays lasting several seconds, our delay function may wait too long for delays lasting under one second.

timedifftime函数的一个警告是C 标准从不指定粒度。大多数实现的粒度为一秒。虽然这对于持续几秒的延迟是没问题的,但我们的延迟函数可能会等待一秒以下的延迟太久。

There is a portable standard C alternative: the clockfunction.

有一个可移植的标准 C 替代方案:clock函数。

The clockfunction returns the implementation's best approximation to the processor time used by the program since the beginning of an implementation-defined era related only to the program invocation. To determine the time in seconds, the value returned by the clockfunction should be divided by the value of the macro CLOCKS_PER_SEC.

clock函数返回实现对程序使用的处理器时间的最佳近似值,自一个实现定义的时代开始,仅与程序调用相关。要确定以秒为单位的时间,clock应将函数返回的值除以宏的值CLOCKS_PER_SEC

The clockfunction solution is quite similar to our timefunction solution:

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);
}

There is a caveat in this case similar to that of timeand difftime: the granularity of the clockfunction is left to the implementation. For example, machines with 32-bit values for clock_twith a resolution in microsecondsmay end up wrapping the value returned by clockafter 2147 seconds (about 36 minutes).

在这种情况下有一个类似于timeand的警告difftimeclock函数的粒度留给实现。例如,具有clock_t微秒为单位的分辨率的32 位值的机器最终可能会clock在 2147 秒(大约 36 分钟)后包装返回的值。

As such, consider using the timeand difftimeimplementation of the delay function for delays lasting at least one second, and the clockimplementation for delays lasting under one second.

因此,请考虑对持续至少一秒的延迟使用timedifftime实现延迟函数,以及对持续一秒以下的延迟使用实现。clock

A final word of caution: clockreturns processor timerather than calendar time; clockmay not correspond with the actual elapsed time (e.g. if the process sleeps).

最后提醒一句:clock返回处理器时间而不是日历时间clock可能与实际经过的时间不一致(例如,如果进程休眠)。

回答by mouviciel

For delays as large as one minute, sleep()is a nice choice.

对于sleep()长达一分钟的延迟,是一个不错的选择。

If someday, you want to pause on delays smaller than one second, you may want to consider poll()with a timeout.

如果有一天,您想暂停小于一秒的延迟,您可能需要考虑poll()超时。

Both are POSIX.

两者都是POSIX。

回答by waffle paradox

Try sleep(int number_of_seconds)

尝试 sleep(int number_of_seconds)

回答by waffle paradox

sleep(int)works as a good delay. For a minute:

sleep(int)作为一个很好的延迟。一分钟:

//Doing some stuff...
sleep(60); //Freeze for A minute
//Continue doing stuff...

回答by ex nihilo

There are no sleep()functions in the pre-C11 C Standard Library, but POSIX does provide a few options.

sleep()C11 之前的 C 标准库中没有函数,但 POSIX 确实提供了一些选项。

The POSIX function sleep()(unistd.h) takes an unsigned intargument for the number of seconds desired to sleep. Although this is not a Standard Library function, it is widely available, and glibc appears to support it even when compiling with stricter settings like --std=c11.

POSIX 函数sleep()(unistd.h) 接受一个unsigned int参数来表示想要休眠的秒数。尽管这不是标准库函数,但它被广泛使用,即使在使用更严格的设置(如--std=c11.

The POSIX function nanosleep()(time.h) takes two pointers to timespecstructures as arguments, and provides finer control over the sleep duration. The first argument specifies the delay duration. If the second argument is not a null pointer, it holds the time remaining if the call is interrupted by a signal handler.

POSIX 函数nanosleep()(time.h) 将两个指向timespec结构的指针作为参数,并提供对睡眠持续时间的更好控制。第一个参数指定延迟持续时间。如果第二个参数不是空指针,它会保存调用被信号处理程序中断时的剩余时间。

Programs that use the nanosleep()function may need to include a feature test macroin order to compile. The following code sample will not compile on my linux system without a feature test macro when I use a typical compiler invocation of gcc -std=c11 -Wall -Wextra -Wpedantic.

使用该nanosleep()函数的程序可能需要包含一个功能测试宏才能进行编译。当我使用典型的编译器调用gcc -std=c11 -Wall -Wextra -Wpedantic.

POSIX once had a usleep()function (unistd.h) that took a useconds_targument to specify sleep duration in microseconds. This function also required a feature test macro when used with strict compiler settings. Alas, usleep()was made obsolete with POSIX.1-2001 and should no longer be used. It is recommended that nanosleep()be used now instead of usleep().

POSIX 曾经有一个usleep()函数 (unistd.h),它接受一个useconds_t参数来指定以微秒为单位的睡眠持续时间。当与严格的编译器设置一起使用时,此函数还需要一个功能测试宏。唉,usleep()在 POSIX.1-2001 中已经过时,不应再使用。建议nanosleep()使用 now 而不是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;
}

Addendum:

附录:

C11 does have the header threads.hproviding thrd_sleep(), which works identically to nanosleep(). GCC did not support threads.huntil 2018, with the release of glibc 2.28. It has been difficult in general to find implementations with support for threads.h(Clang did not support it for a long time, but I'm not sure about the current state of affairs there). You will have to use this option with care.

C11确实有头threads.h提供thrd_sleep(),这同样工作到nanosleep()。GCCthreads.h直到 2018 年才支持,随着glibc 2.28的发布。通常很难找到支持threads.h(Clang 很长时间不支持它,但我不确定那里的当前状况)的实现。您必须谨慎使用此选项。

回答by Craig D

// Provides ANSI C method of delaying x milliseconds

// 提供延迟 x 毫秒的 ANSI C 方法

#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();
}

回答by leo60228

C11 has a function specifically for this:

C11 有一个专门用于此的功能:

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

void sleep(time_t seconds) {
    struct timespec time;
    time.tv_sec = seconds;
    time.tv_nsec = 0;
    while (thrd_sleep(&time, &time)) {}
}

int main() {
    puts("Sleeping for 5 seconds...");
    sleep(5);
    puts("Done!");
    return 0;
}

Note that this is only available starting in glibc 2.28.

请注意,这仅从 glibc 2.28 开始可用。