在C语言中实现时间延迟函数

3
我想使用空循环实现延迟函数。但是,完成一次循环所需的时间取决于编译器和计算机。我希望我的程序能够自己确定时间并延迟指定的时间量。有没有人能给我任何想法如何做到这一点呢?
注:有一个名为delay()的函数,可以暂停系统指定的毫秒数。是否可能在不使用此函数的情况下暂停系统?

1
delay()函数是操作系统和机器相关的。它不是C语言的某种神奇函数,而只是由ANSI或POSIX采用的标准接口。它必须在特定硬件的内核级别上实现,这意味着它也与编译器/机器有关。 - alan7678
1
如果您不是在内核级别的编程中,即在unix、windows等操作系统中的用户应用程序中,为什么要重复造轮子呢?如果您处于内核级别,您必须了解硬件,如何使用计时器等寄存器。 - alan7678
1
从C11开始,标准现在提出了一个独立于操作系统的接口thrd_sleep。不幸的是,还没有所有编译器实现它,但它即将到来。 - Jens Gustedt
1
类似于Linux中的usleep() /nanosleep() 或Windows中的Sleep()肯定会起作用,但我的经验是,每当您认为需要在程序中延迟时,那是因为您没有足够地考虑到您真正需要的是什么。您究竟想要实现什么? - Lee Daniel Crocker
3个回答

3
首先,你绝不能坐在一个什么都不做的循环中。这不仅浪费能源(因为它让你的CPU 100% 忙于计算循环计数器),而且在多任务系统中,它还会降低整个系统的性能,因为你的进程一直在获取时间片,因为它看起来正在做某些事情。
接下来的问题是...我不知道任何delay()函数。这不是标准C。实际上,在C11之前,根本没有关于这种东西的标准。
POSIX来拯救,有usleep(3)(已弃用)和nanosleep(2)。如果你在一个符合POSIX标准的系统上,那么你可以使用它们。它们会阻塞(意味着你的操作系统调度程序知道它们没事可做,并将它们安排在调用结束后),所以你不会浪费CPU功率。
如果您正在使用Windows操作系统,想要在代码中使用延迟,您只能使用Sleep()函数。请注意,此函数以毫秒为单位计算时间,但通常只有约15ms的精度。通常足够好,但并非总是如此。如果您需要更好的精度,请使用timeBeginPeriod()来请求更多的定时器中断... {{code>timeBeginPeriod(1);}}将请求每毫秒一个定时器中断。不要忘记在不再需要精度时使用相同的值调用timeEndPeriod(),因为更多的定时器中断会增加系统的负担,从而浪费更多的能源。
我最近开发了一个小游戏,遇到了类似的问题。我需要在10毫秒的间隔内进行常量时钟。我生成了 适用于符合POSIX标准的系统适用于Windows的代码。这些代码中的 ticker_wait() 函数仅会暂停,直到下一个时钟周期。如果您的初衷是解决时间问题,这可能有所帮助。

2

除非你在实时操作系统上,否则你直接编写的任何程序都不会很准确。你需要使用系统函数来休眠一段时间,例如Linux中的usleep或Windows中的Sleep

由于操作系统可能比预期的时间早或晚地中断进程,因此你应该在休眠前后获取系统时间以确定你实际休眠了多长时间。

编辑:

在Linux上,你可以使用具有微秒分辨率的gettimeofday获取当前系统时间(实际时钟是否那么准确是另一回事)。在Windows上,你可以使用类似的GetSystemTimeAsFileTime函数:

int gettimeofday(struct timeval *tv, struct timezone *tz)
{
    const unsigned __int64 epoch_diff = 11644473600000000;
    unsigned __int64 tmp;
    FILETIME t;

    if (tv) {
        GetSystemTimeAsFileTime(&t);

        tmp = 0;
        tmp |= t.dwHighDateTime;
        tmp <<= 32;
        tmp |= t.dwLowDateTime;

        tmp /= 10;
        tmp -= epoch_diff;
        tv->tv_sec = (long)(tmp / 1000000);
        tv->tv_usec = (long)(tmp % 1000000);
    }

    return 0;
}

你是在说使用time()函数获取系统时间吗? - Rohan Gayen
gettimeofday(2)自SUS v4以来已经过时,您应该推荐使用clock_gettime(2) - Filipe Gonçalves
而且:使用系统函数来休眠并不一定比自己编写更准确。正如你所说,Linux 不是实时操作系统,因此无论如何都可能会发生延迟。 - Filipe Gonçalves

1
你可以做一些事情,比如找到某个时间点的确切时间,然后将其保留在一个 while 循环中,该循环会重新检查时间,直到它达到你想要的时间为止。然后它就会跳出循环并继续执行程序的其余部分。不过,我不确定循环比只使用延迟函数有多大好处。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接