implement time delay in c

后端 未结 17 1761
我在风中等你
我在风中等你 2020-11-30 05:43

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 w

相关标签:
17条回答
  • 2020-11-30 06:23

    Check sleep(3) man page or MSDN for Sleep

    0 讨论(0)
  • 2020-11-30 06:23

    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.

    0 讨论(0)
  • 2020-11-30 06:25

    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.
    }
    
    0 讨论(0)
  • 2020-11-30 06:26

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

    0 讨论(0)
  • 2020-11-30 06:27

    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.

    0 讨论(0)
提交回复
热议问题