Is there an alternative for sleep() in C?

后端 未结 16 1873
无人及你
无人及你 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:16

    You talk about "embedded programming" in the OP. If you're doing embedded work and need something like sleep(), there are often hardware counters/timers available. This will vary from architecture to architecture, so have a look at the datasheet.

    If you're not doing embedded work, I apologize :)

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

    I found the function in this post (http://cboard.cprogramming.com/c-programming/111229-how-use-sleep-function.html) and it works:

    #include <stdio.h>
    #include <windows.h>
    
    int main()
    {
        puts("Hello \n");
        /* in windows.h is declared the Sleep (upper S) function and it takes time in 
    miliseconds */
        Sleep(3000);
        puts("World \n");
        return 0;
    }
    
    0 讨论(0)
  • 2020-12-02 15:20

    In a unix-derivative OS, you would probably schedule a signal() call, and your code would simply block the code until the signal is raised. Signals are intended for the purpose, and they are very simple and efficient.

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

    The kind of loop you describe is called a "busy wait". In real operating systems, sleeping does not cause a busy wait; it tells the operating system to not schedule the process in until the sleep period is over.

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

    You would not use the code you published to sleep on an embedded system. A decent compiler would entirely remove it, and even if your compiler does not remove it is suboptimal, since running the processor in a tight loop will burn power, which is an issue for embedded system. Even systems not running on battery care about power usage, since lower power usage means cheaper power supplies and cooling.

    The way you normally do this is your CPU will implement some sort of IDLE or SLEEP instructions, that will cause it to temporarily stop processing commands. An external interrupt line connected to a timer circuit will wake the processor back up at regular intervals, and which point the CPU checks to see if it has been asleep for long enough, and if not it goes back to sleep.

    //Pseudo code
    int start = getTime();
    int end = start + sleepTime;
    
    while (getTime() < end) {
           asm("SLEEP");
    }
    

    The exact details vary from processor to processor. If you are running as a process on an OS the sleep call generally just tells the scheduler to suspend your process, and then the kernel decides whether to schedule another process or to sleep the CPU. Also, the above code will not be adequete for real time systems, which want deadline guarantees, etc. In those cases you will need to get the time in the loop, know the duration of the time interrupt so ou know if you can resleep without blowing the deadline, and potentially reprogram the timer hardware or busy wait.

    0 讨论(0)
  • 2020-12-02 15:27
    #include <Windows.h>
    
    static NTSTATUS(__stdcall *NtDelayExecution)(BOOL Alertable, PLARGE_INTEGER DelayInterval) = (NTSTATUS(__stdcall*)(BOOL, PLARGE_INTEGER)) GetProcAddress(GetModuleHandle("ntdll.dll"), "NtDelayExecution");
    
    static NTSTATUS(__stdcall *ZwSetTimerResolution)(IN ULONG RequestedResolution, IN BOOLEAN Set, OUT PULONG ActualResolution) = (NTSTATUS(__stdcall*)(ULONG, BOOLEAN, PULONG)) GetProcAddress(GetModuleHandle("ntdll.dll"), "ZwSetTimerResolution");
    
    
    
    
    static void SleepShort(float milliseconds) {
        static bool once = true;
        if (once) {
            ULONG actualResolution;
            ZwSetTimerResolution(1, true, &actualResolution);
            once = false;
        }
    
        LARGE_INTEGER interval;
        interval.QuadPart = -1 * (int)(milliseconds * 10000.0f);
        NtDelayExecution(false, &interval);
    }
    
    0 讨论(0)
提交回复
热议问题