在c中实现时间延迟

dev*_*per 29 c time sleep timedelay delay

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

我需要在C中实现延时.

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

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

pax*_*blo 37

在标准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.
}
Run Code Online (Sandbox Code Playgroud)

顺便说一下,这假定time()返回1秒的分辨率值.我不认为这是标准规定的,所以你可能需要调整它.


为了澄清这一点,我知道用ISO C99做这件事的唯一方法(问题只标记为"C",这通常意味着便携式解决方案是可取的,当然,特定于供应商的解决方案仍可给予).

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

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

然而Ç指定任何有关在托管环境中操作系统的详细信息,以及这个答案是ISO C和ISO C单独(所以没有用的sleep,select,Win32 API调用或类似的东西).

请记住,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.
}
Run Code Online (Sandbox Code Playgroud)

  • 什么abt的CPU负载? (3认同)
  • @paxdiablo:不,实际上它不会......其中一个CPU的时钟频率将上升到100%.并且CPU负载很重要,特别是如果你在笔记本电脑上,当CPU最大化时会产生热量,并且热量会缩短计算机的使用寿命.在一个可能无关紧要的旧固定器上,这就是windows处理它的方式(当无法做到时,无限循环无所事事).我想今天操作系统使用先进的省电技术,但我知道Linux内核发出了一个hlt指令,就像我12岁那样. (3认同)
  • sleep(sec)显然是ISO/IEC 9945-1:1990(POSIX 1)标准,只有微软才能做到这一点,而世界其他地方只做一种方式...... (3认同)
  • @Frank,我认为`volatile sig_atomic_t finishing`是信号处理程序和主线程之间共享变量的正确声明.我只是想指出,经常有外部要求必须得到尊重...... (3认同)

Fra*_*ank 16

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

#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
}
Run Code Online (Sandbox Code Playgroud)

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

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
}
Run Code Online (Sandbox Code Playgroud)

必须对waitloop变量进行微调,这些变量对于我的计算机来说非常接近,但频率规模使得现代桌面系统非常不精确; 所以不要在那里使用,除非你裸露金属而不做这些东西.


Vil*_*ray 6

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

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);
}
Run Code Online (Sandbox Code Playgroud)

使用timedifftime函数的一个警告是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);
}
Run Code Online (Sandbox Code Playgroud)

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

因此,可以考虑使用timedifftime延误持久延时功能的实现至少一个第二clock延误持续执行一秒钟.

最后提醒:clock返回处理器时间而不是日历时间 ; clock可能与实际经过的时间不对应(例如,如果过程休眠).