在c中实现时间延迟

时间:2010-10-14 05:36:38

标签: c time sleep delay timedelay

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

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

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

这有意义吗?任何人都可以帮助我吗?

18 个答案:

答案 0 :(得分: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.
}

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


为了澄清,这是唯一的方式,我知道用ISO C99做到这一点(并且问题被标记为“C”,这通常意味着便携式解决方案是尽管如此,当然,仍然可以提供特定于供应商的解决方案。)

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

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

但是C指定 nothing 关于托管环境中的操作系统详细信息,并且这个答案仅适用于ISO C和ISO C(因此不使用sleepselect ,Win32 API调用或类似的东西)。

请记住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.
}

答案 1 :(得分: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
}

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

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变量进行微调,这些变量对于我的计算机来说非常接近,但是对于现代桌面系统来说,频率规模使得它非常不精确;所以不要在那里使用,除非你对金属裸露并且不做这样的事情。

答案 2 :(得分:9)

答案 3 :(得分:6)

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

C标准保证

difftime可以在中返回两个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);
}

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

在这种情况下,有一个警告类似于timedifftime的警告:clock函数的粒度留给实现。例如,具有<{1}}的32位值且分辨率为微秒的计算机可能会在2147秒(约36分钟)后包装clock_t返回的值。< / p>

因此,请考虑使用延迟函数的clocktime实现延迟至少一秒,并difftime执行延迟持续一秒钟

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

答案 4 :(得分:3)

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

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

两者都是POSIX。

答案 5 :(得分:1)

尝试sleep(int number_of_seconds)

答案 6 :(得分:1)

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

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

答案 7 :(得分:1)

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

POSIX函数sleep()(unistd.h)采用unsigned int自变量表示所需的睡眠秒数。尽管这不是标准库函数,但它可以广泛使用,即使使用--std=c11之类的更严格的设置进行编译,glibc似乎也支持它。

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

使用nanosleep()函数的程序可能需要包含feature test macro才能进行编译。当我使用gcc -std=c11 -Wall -Wextra -Wpedantic的典型编译器调用时,以下代码示例将无法在没有功能测试宏的Linux系统上编译。

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

答案 8 :(得分:0)

对于 Linux 操作系统上的短暂延迟(比如几微秒),您可以使用“usleep”:

// C Program to perform short delays
#include <unistd.h>
#include <stdio.h>

int main(){
    printf("Hello!\n");
    usleep(1000000); // For a 1-second delay
    printf("Bye!\n);
    return 0;

答案 9 :(得分:0)

您使用的是什么操作系统?
我知道在Windows上,您可以执行以下操作:

//include crap
#include <windows.h>

int main () {
  //do things
  Sleep(/* ur wait time in ms */);// wait for param1 ms
  //continue to do things
}

答案 10 :(得分:0)

在gcc中用于C语言。 #include

然后使用Sleep(); ///使用大写字母S的sleep()。不使用s的sleep()。

// Sleep(1000)是1秒///也许。

clang支持sleep(),sleep(1)的延迟时间为1秒。

答案 11 :(得分:0)

C11具有专门的功能:

try (Workbook wb = WorkbookFactory.create(stream)) {

  //parsing the file content ...

} catch (IOException e) {
   log.error("hopefully something clear", e);
   throw new CustomException(Errors.CUSTOM_ERROR_CODE_FOR_THIS_PARTICULAR_ISSUE);
}

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

答案 12 :(得分:0)

//提供了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();
}

答案 13 :(得分:0)

如果您确定要等待并且永远不会中断,请在POSIX中使用sleep或在Windows中使用Sleep。在POSIX中,睡眠需要几秒钟的时间,所以如果你想让时间更短,那么像usleep()这样的变种会使用微秒。在Windows中睡眠需要几毫秒,很少需要比它更精细的粒度。

您可能希望等待一段时间但希望允许中断,可能是在紧急情况下。睡眠可以被信号中断,但在这种情况下有更好的方法。

因此,我实际上在实践中发现你所做的是等待事件或条件变量超时。

在Windows中,您的通话为WaitForSingleObject。在POSIX中,它是pthread_cond_timedwait

在Windows中,您还可以使用WaitForSingleObjectEx,然后通过调用QueueUserAPC实际上可以通过任何排队任务“中断”您的线程。 WaitForSingleObject(Ex)将返回一个代码,用于确定退出的原因,因此您将知道它何时返回“TIMEDOUT”状态,确实超时。您希望它终止时设置它正在等待的事件。

使用pthread_cond_timedwait,您可以发出广播条件变量的信号。 (如果有几个线程正在等待同一个线程,则需要进行广播以将它们全部唤醒)。每次循环时都应检查条件。您的线程可以获取当前时间并查看它是否已通过,或者它可以查看是否已满足某些条件以确定要执行的操作。如果你有某种队列,你可以检查它。 (您的线程将自动锁定用于等待条件变量的互斥锁,因此当它检查条件时它只能访问它)。

答案 14 :(得分:0)

你可以简单地调用delay()函数。因此,如果您想在3秒内延迟该过程,请拨打延迟(3000)...

答案 15 :(得分:0)

答案 16 :(得分:-1)

编写此代码:

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

}

答案 17 :(得分:-1)

system("timeout /t 60"); // waits 60s. this is only for windows vista,7,8
system("ping -n 60 127.0.0.1 >nul"); // waits 60s. for all windows