32

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

I need to implement a time delay in 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?

Wok
  • 4,468
  • 5
  • 34
  • 56
developer
  • 6,414
  • 14
  • 45
  • 56

18 Answers18

43

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

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


In order to clarify, this is the only way 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).

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.

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 nothing about 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).

And keep in mind that POSIX sleep can be interrupted by signals. If you are going to go down that path, you need to do something like:

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.
}
paxdiablo
  • 772,407
  • 210
  • 1,477
  • 1,841
  • 1
    Yes, there will be a CPU load, but any decent OS (assuming pre-emptively multi-tasking) will detect that and drop the dynamic priority accordingly. And, if it's not, the CPU load doesn't matter (if it's co-operatively multitasked, you may want to look into a `yield` function). The reason I posted this is because there is no ISO-C portable way to do it and the question is tagged only "C" (`sleep`, while useful, is _not_ standard). – paxdiablo Oct 14 '10 at 06:04
  • 3
    @paxdiablo: No, actually it wont... The clock frequency of one of the CPUs will rise to 100% percent. And the CPU load matters, especially if you're on a laptop, when the CPU is maxed up it generates heat, and heat shortens the computers lifetime. On an old stationary that does probably not matter, this is how windows handles it (en endless loop doing nothing when there is noting to do). I guess that today OSes uses advanced power saving techinques, but I know that the Linux kernel issued a hlt instruction, same did I when I was 12. – Frank Oct 14 '10 at 06:17
  • @paxdiablo: let `retTime` be of type `time_t`. What systems do you refer to? It will hit CPU hardly in any system. Doesn't it matter to you? Besides that, this is a typical task for the OS, not for the language. – jweyrich Oct 14 '10 at 06:17
  • 3
    sleep( sec ) is apparently a ISO/IEC 9945-1:1990 (POSIX 1) standard, it is just Microsoft that does their way while the rest of the world does one way... – Frank Oct 14 '10 at 06:23
  • 1
    @Frank, if you're saying Windows dynamic priority won't be adjusted, you're wrong. Threads that voluntarily relinquish the CPU have the dynamic priorities boosted. Those that are forced out after using their entire time slice have their priorities reduced (though not below their baseline, from memory). This will tend to favour well-behaved apps over others. You're right that it will still consume CPU but again, if you're on an OS that allows `sleep` to put your process in a waiting queue (and halts the CPU when only the idle task is running), use it. It's still not standard. – paxdiablo Oct 14 '10 at 06:26
  • @jweyrich, yes it will hit CPU hard. And there are situations where that doesn't matter (say embedded non-multitasking or even desktops with proper dynamic priority adjustments). See my comment to Frank. The question is tagged C with no mention of Linux or Windows. That's why I posted this answer, because it's the _only_ way I know of to achieve this with C alone. If you find something in C99 that states otherwise, I'll be happy to delete the answer. – paxdiablo Oct 14 '10 at 06:28
  • Feel free to clarify, @Frank, but the only part of my comment that your answer "No, actually, it won't" seemed to made sense to, was the "any decent OS ..." bit. – paxdiablo Oct 14 '10 at 06:31
  • I have a really good OS, it is more than decent. And there usually isn't any misbehaving programs, except for Adobe Flash Player. Most people using my OS would complain to the author if s/hes program is misbehaving and maybe even send a patch or not use the program at all. – Frank Oct 14 '10 at 06:47
  • I'm not entirely sure what you're trying to say there, Frank, it seemed a bit incongruous to me. I'm not disparaging your choice of OS. If you'd like to point out exactly what text of mine your "No, actually, it won't" comment applied to, we can discuss it. I've already stated _why_ I posted this answer. If you don't find it useful in your (in my opinion, limited) concept of a C environment, feel free to vote it down, that's what the voting system is for, after all. – paxdiablo Oct 14 '10 at 06:54
  • "[...] any decent OS (assuming pre-emptively multi-tasking) will detect that and drop the dynamic priority accordingly. And, if it's not, the CPU load doesn't matter [...]" that is what I said "No, actually, it won't" on. And I've already voted it down. And I've already stated why the CPU load does matter. Not that it gets hot, it also drains power. Guess what? My laptops battery last longer since I throw Windows out the window. And I have all kind of 3D-desktop fx that probably drains their share. Battery still lasts longer. – Frank Oct 14 '10 at 07:03
  • @paxdiablo: I support the affirmation that there's no standard way, but IMHO the loop solution proposed in `waitFor` should never be used in any multitasking system that exposes wait/suspend mechanisms. I didn't downvote because the answer is not incorrect after all. It was just lacking informations that you included @ revision 4. – jweyrich Oct 14 '10 at 07:14
  • @Frank: well, that makes more sense then, that it was the "if it's not, the CPU load doesn't matter" comment. However, I still stand by my _answer_. You're free to vote as you will. I would hope the edits made a while ago introducing the caveat that you should use a better way _if provided_, would sway you but, if not, we can just agree to disagree. Cheers. – paxdiablo Oct 14 '10 at 07:15
  • No probs, @jweyrich, if we all agreed, SO would be a pretty boring place :-) – paxdiablo Oct 14 '10 at 07:16
  • @paxdiablo: Guess you're the one downvoting my answer. – Frank Oct 14 '10 at 07:30
  • I prefer not to do that to "competing" answers though I have to admit I'm tempted :-) The community can decide the relative merits. – paxdiablo Oct 14 '10 at 07:36
  • Wrapping sleep in a while that way is pretty bad, if the sleep was interrupted by a signal then it should probably be respected. The user might actually wanna terminate the program - who wants to wait minutes before a program quits? – Frank Oct 14 '10 at 07:37
  • Fair enough comment. I've added a way to fix that although I don't doubt someone will be able to pick holes in the method. The important thing I was trying to raise was just that you shouldn't rely on `sleep` actually honouring your requested delay. The means to fix it are an implementation issue. – paxdiablo Oct 14 '10 at 07:42
  • @Frank, sometimes time delays are there for reasons related to real world processes. If the furnace needs 10 minutes to cool, then it might be rather important that the program wait all 10 of those minutes. Of course, I spend my days inside of embedded systems, and usually not working on desktop software, so my perspective is warped... – RBerteig Oct 14 '10 at 08:00
  • @RBerteig: I understand you, and now paxdiablo has kinda fixed his function too. But still thinks that he must mark the variable with `volatile`. – Frank Oct 14 '10 at 08:29
  • 3
    @Frank, I think `volatile sig_atomic_t finishing` is the right declaration for a variable shared between a signal handler and the main thread. I just wanted to point out that there are often outside requirements that must be respected... – RBerteig Oct 14 '10 at 08:35
  • Why didn't you declare retTime ? – Amin NAIRI Apr 13 '16 at 14:42
17

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.

Frank
  • 2,440
  • 2
  • 19
  • 21
  • +1 to offset an IMHO undeserved downvote. On the other hand, you are clearly assuming an OS with useful system calls and the actual question only mentions standard C which as Pax points out lacks any kind of delay call. A very large amount of C code is running on platforms without operating systems. Although some mechanism similar to `sleep()` is often a good thing to create in such platforms, it isn't required by any of the C standards. – RBerteig Oct 14 '10 at 08:04
  • I was thinking on writing of how to do it on microprocessors to without an OS, but did not quite felt to. Not really my field. – Frank Oct 14 '10 at 08:24
  • 1
    @Frank, Even with no OS, you often have a counter implemented in hardware that counts cycles of some clock. So one way is to read that counter, predict a future value, and spin in a loop until the counter reaches the value. That works for short enough waits that the counter isn't wrapping more than once while waiting. In small CPUs you sometimes have to resort to hand-tuned loops where you know exactly how many cycles are consumed per iteration. There is always a way, but it may not be pretty. – RBerteig Oct 14 '10 at 08:40
  • Precisely, it may not always be pretty. But I wounder, aren't there any microcomputers where you can set an interrupt and issue hlt to save power? – Frank Oct 14 '10 at 08:48
  • 1
    @Frank: some have it. For instance, PIC32MX has 2 types of timers. Type A has its own oscillator, while B doesn't. Both permit you to select the prescaler. – jweyrich Oct 14 '10 at 09:04
  • For the first one, I would suggest a float instead of an integer. – Aetricity Feb 02 '16 at 00:40
  • Shadowing the `wait` system call may not be desirable; perhaps use a different name. – tripleee Apr 21 '16 at 05:00
9

Check sleep(3) man page or MSDN for Sleep

6

Although many implementations have the time function return the current time in seconds, there is no guarantee that every implementation will do so (e.g. some may return milliseconds rather than seconds). As such, a more portable solution is to use the difftime function.

difftime is guaranteed by the C standard to return the difference in time in seconds between two time_t values. As such we can write a portable time delay function which will run on all compliant implementations of the C standard.

#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 time and difftime functions is that the C standard never 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.

There is a portable standard C alternative: the clock function.

The clock function 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 clock function should be divided by the value of the macro CLOCKS_PER_SEC.

The clock function solution is quite similar to our time function solution:

#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 time and difftime: the granularity of the clock function is left to the implementation. For example, machines with 32-bit values for clock_t with a resolution in microseconds may end up wrapping the value returned by clock after 2147 seconds (about 36 minutes).

As such, consider using the time and difftime implementation of the delay function for delays lasting at least one second, and the clock implementation for delays lasting under one second.

A final word of caution: clock returns processor time rather than calendar time; clock may not correspond with the actual elapsed time (e.g. if the process sleeps).

Vilhelm Gray
  • 10,078
  • 8
  • 55
  • 108
3

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

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

Both are POSIX.

mouviciel
  • 62,742
  • 10
  • 106
  • 135
1

Try sleep(int number_of_seconds)

waffle paradox
  • 2,710
  • 16
  • 19
1

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

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

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

The POSIX function sleep() (unistd.h) takes an unsigned int argument 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.

The POSIX function nanosleep() (time.h) takes two pointers to timespec structures 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.

Programs that use the nanosleep() function may need to include a feature test macro in 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.

POSIX once had a usleep() function (unistd.h) that took a useconds_t argument 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().

#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.h providing thrd_sleep(), which works identically to nanosleep(). GCC did not support threads.h until 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.

ad absurdum
  • 15,925
  • 4
  • 28
  • 49
0

Is it timer?

For WIN32 try http://msdn.microsoft.com/en-us/library/ms687012%28VS.85%29.aspx

ruslik
  • 13,918
  • 1
  • 33
  • 38
0

you can simply call delay() function. So if you want to delay the process in 3 seconds, call delay(3000)...

Owen
  • 3,793
  • 15
  • 53
  • 75
0

If you are certain you want to wait and never get interrupted then use sleep in POSIX or Sleep in Windows. In POSIX sleep takes time in seconds so if you want the time to be shorter there are varieties like usleep() which uses microseconds. Sleep in Windows takes milliseconds, it is rare you need finer granularity than that.

It may be that you wish to wait a period of time but want to allow interrupts, maybe in the case of an emergency. sleep can be interrupted by signals but there is a better way of doing it in this case.

Therefore I actually found in practice what you do is wait for an event or a condition variable with a timeout.

In Windows your call is WaitForSingleObject. In POSIX it is pthread_cond_timedwait.

In Windows you can also use WaitForSingleObjectEx and then you can actually "interrupt" your thread with any queued task by calling QueueUserAPC. WaitForSingleObject(Ex) will return a code determining why it exited, so you will know when it returns a "TIMEDOUT" status that it did indeed timeout. You set the Event it is waiting for when you want it to terminate.

With pthread_cond_timedwait you can signal broadcast the condition variable. (If several threads are waiting on the same one, you will need to broadcast to wake them all up). Each time it loops it should check the condition. Your thread can get the current time and see if it has passed or it can look to see if some condition has been met to determine what to do. If you have some kind of queue you can check it. (Your thread will automatically have a mutex locked that it used to wait on the condition variable, so when it checks the condition it has sole access to it).

CashCow
  • 29,087
  • 4
  • 53
  • 86
0

// Provides ANSI C method of delaying x milliseconds

#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();
}
Craig D
  • 121
  • 5
0

C11 has a function specifically for this:

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

leo60228
  • 429
  • 6
  • 17
0

for C use in gcc. #include <windows.h>

then use Sleep(); /// Sleep() with capital S. not sleep() with s .

//Sleep(1000) is 1 sec /// maybe.

clang supports sleep(), sleep(1) is for 1 sec time delay/wait.

shyed2001
  • 15
  • 5
0

What operating system are you using?
I know that on windows, you can do something like this:

//include crap
#include <windows.h>

int main () {
  //do things
  Sleep(/* ur wait time in ms */);// wait for param1 ms
  //continue to do things
}
  • When adding an answer to an older question with sixteen existing answers including an accepted answer it is very important to point out what new aspect of the question your answer addresses. It is also unlikely that an answer that starts with a question is going to get a response after nine years. – Jason Aller Aug 04 '20 at 19:46
0

For short delays (say, some microseconds) on Linux OS, you can use "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;
Sina
  • 1
  • 1
  • `usleep` was POSIX (this is why you might find it in Linux), but was obsoleted twenty years ago, and completely removed from the POSIX spec over a decade ago; [even the Linux man pages say the same thing](https://linux.die.net/man/3/usleep). You should used the newer POSIX functions [`sleep`](https://linux.die.net/man/3/sleep) and [`nanosleep`](https://linux.die.net/man/2/nanosleep) instead, which are also supported on Linux. [My answer on this page](https://stackoverflow.com/a/53809070/6879826) details these issues and even provides some usage tips. – ad absurdum Feb 11 '21 at 20: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
p2013
  • 430
  • 3
  • 6
  • 12
-2

Write this code :

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

}