Is there an alternative for sleep() in C?

后端 未结 16 1875
无人及你
无人及你 2020-12-02 14:55

In traditional embedded programming, we will give a delay function like so:

for(i=0;i<255;i++)
   for(j=0;j<255;j++);

In the micropro

相关标签:
16条回答
  • 2020-12-02 15:32

    If you're using for-loops, you'd better know what they compile to and how long those instructions take at your given clock speed, and ensure the CPU runs your instructions and nothing else (this can be done in embedded systems but it's tricky since it disallows interrupts).

    Otherwise, you won't be able to tell how long it's really going to take.

    Early PC games had this problem - they were built for a 4.7MHz PC and, when the faster computers came along, they were unplayable.

    The best way a 'sleep' can work is for the CPU to know what time it is at any given point. Not necessarily the actual time (7:15 am) but at least the relative time (8612 seconds since some point in time).

    That way it can apply a delta to the current time and wait in a loop until the current+delta is reached.

    Anything that relies on number CPU cycles is inherently unreliable as the CPU may go off to another task and leave your loop hanging.

    Let's say you have a memory-mapped 16-bit I/O port which the CPU increments once a second. Let's also assume it's at memory location 0x33 in your embedded system, where ints are also 16 bits. A function called sleep then becomes something like:

    void sleep (unsigned int delay) {
        unsigned int target = peek(0x33) + delay;
        while (peek(0x33) != target);
    }
    

    You'll have to ensure that peek() returns the memory contents every time (so optimizing compilers don't muck up the logic) and that your while statement runs more than once per second so you don't miss the target, but these are operational issues that don't affect the concept I'm presenting.

    0 讨论(0)
  • 2020-12-02 15:34

    There's more information on how sleep() works here

    By the way, busy waiting is not necessarily for amateurs--although it does burn processor that you may want to use for some other purpose. If you are using a time source, you are limited to the granularity of that source. E.G. if you have a 1 ms timer, and want to way 500 uS, you have a problem. If your embedded system can handle the fact that you'll be buzzing in a loop for 500 uSec, that might be acceptable. And even if you have a timer with your desired granularity, you also need to get an interrupt off that timer at the right time...then dispatch ot the interrupt handler...then get to your code. Sometimes a busy loop is the most expedient solution. Sometimes.

    0 讨论(0)
  • 2020-12-02 15:34

    Busy-waiting is for amateurs even in an embedded system, use a real time source.

    0 讨论(0)
  • 2020-12-02 15:35

    Alternatives depend in what you are trying to do and what OS you are on.

    If you just want to waste time, then these might help:

    On most unix-type systems you'll find a 'usleep' function, which is more or less like sleep with greater resolution. Be careful with that one because it usually can not sleep for just one microsecond.

    On some unix-type systems, the select system call can be used with all file descriptor sets zero in order to get a fairly accurate sub-second wait.

    On windows systems, you have Sleep, which is pretty much the same, but taking a number of milliseconds.

    In a multi-tasking operating system, a sleep function can sometimes be given 0 as a parameter. This generally causes the function to give up it's timeslice, but be re-scheduled immediately if no other task is ready to run.

    0 讨论(0)
  • 2020-12-02 15:37

    sleep actually interfaces with operating system, where sleeping processes are placed outside of scheduling queue. I usually use:

    poll(0, 0, milliseconds);
    

    for POSIX compliant systems. select also works for windows (they must have a native API (probably called Sleep) for that.)

    0 讨论(0)
  • 2020-12-02 15:38

    Page 20 in 'Threading in C#' by Joseph Albahari has an interesting discussion of this. You cannot sleep for less than 1 ms in .Net but DateTime.Ticks has a granularity of 100-nanoseconds (= 0.1 microseconds) intervals. For controlling my 5 axis CNC stepper I only need to pause for 10 microseconds between step commands. I have used a micro controller to do the nasty looping but I think it is OK hand over a processor for the job if you have a whole bunch anyway, stop the thread when you can. At least it wont always be the same one.

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