You wouldn't with this code, since accurately measuring the time that code takes to execute is a difficult task.

To get to the question posed by your question title (you should really ask one question at a time...) the accuracy of said functions is dictated by the operating system. On Linux, the system clock granularity is 10ms, so timed process suspension via nanosleep() is only guaranteed to be accurate to 10ms, and even then it's not guaranteed to sleep for exactly the time you specify. (See below.)

On Windows, the clock granularity can be changed to accommodate power management needs (e.g. decrease the granularity to conserve battery power). See MSDN's documentation on the Sleep function.

Note that with Sleep()/nanosleep(), the OS only guarantees that the process suspension will last for at least as long as you specify. The execution of other processes can always delay resumption of your process.

Therefore, the key-up event sent by your code above will be sent at least 2.638 seconds later than the key-down event, and not a millisecond sooner. But it would be possible for the event to be sent 2.7, 2.8, or even 3 seconds later. (Or much later if a realtime process grabbed hold of the CPU and didn't relinquish control for some time.)

Answer from cdhowie on Stack Overflow
🌐
GNU
gnu.org › software › hello › manual › libc › Sleeping.html
Sleeping (The GNU C Library)
The sleep function is declared in unistd.h. Resist the temptation to implement a sleep for a fixed amount of time by using the return value of sleep, when nonzero, to call sleep again. This will work with a certain amount of accuracy as long as signals arrive infrequently.
Top answer
1 of 4
6

You wouldn't with this code, since accurately measuring the time that code takes to execute is a difficult task.

To get to the question posed by your question title (you should really ask one question at a time...) the accuracy of said functions is dictated by the operating system. On Linux, the system clock granularity is 10ms, so timed process suspension via nanosleep() is only guaranteed to be accurate to 10ms, and even then it's not guaranteed to sleep for exactly the time you specify. (See below.)

On Windows, the clock granularity can be changed to accommodate power management needs (e.g. decrease the granularity to conserve battery power). See MSDN's documentation on the Sleep function.

Note that with Sleep()/nanosleep(), the OS only guarantees that the process suspension will last for at least as long as you specify. The execution of other processes can always delay resumption of your process.

Therefore, the key-up event sent by your code above will be sent at least 2.638 seconds later than the key-down event, and not a millisecond sooner. But it would be possible for the event to be sent 2.7, 2.8, or even 3 seconds later. (Or much later if a realtime process grabbed hold of the CPU and didn't relinquish control for some time.)

2 of 4
1

Sleep works in terms of the standard Windows thread scheduling. It is accurate up to about 20-50 milliseconds.

So that it's ok for user experience-dependent things. However it's absolutely inappropriate for real-time things.

Beside of this, there're much better ways to simulate keyboard/mouse events. Please see SendInput.

🌐
GNU
gnu.org › software › coreutils › manual › html_node › sleep-invocation.html
sleep invocation (GNU Coreutils 9.8)
Due to shell aliases and built-in sleep functions, using an unadorned sleep interactively or in a script may get you different functionality than that described here.
🌐
Arch Linux Forums
bbs.archlinux.org › viewtopic.php
How does sleep command works? / GNU/Linux Discussion / Arch Linux Forums
you can also "ctrl-c" to cancel sleep while it's waiting. ... It looks like a loop that just continuously counts the number of nanoseconds that have passed to see if you've reached the requested time. Actually keeping track of nanoseconds is handled by timespec.
🌐
GNU
ftp.gnu.org › pub › old-gnu › Manuals › glibc-2.2.5 › html_node › Sleeping.html
The GNU C Library
Resist the temptation to implement a sleep for a fixed amount of time by using the return value of sleep, when nonzero, to call sleep again. This will work with a certain amount of accuracy as long as signals arrive infrequently. But each signal can cause the eventual wakeup time to be off by an additional second or so. Suppose a few signals happen to arrive in rapid succession by bad luck--there is no limit on how much this could shorten or lengthen the wait.
🌐
GNU
gnu.org › software › libc › manual › html_node › Sleeping.html
The GNU C Library - GNU Project - Free Software Foundation (FSF)
This glibc manual version 2.43 (latest) is available in the following formats: · The manual is available for the following releases of glibc:
🌐
Reddit
reddit.com › r/c_programming › explain how the sleep command works.
r/C_Programming on Reddit: Explain how the sleep command works.
March 9, 2022 -

I have the source for the sleep command from coreutils in front of me but I do not quite understand what is actually making sleep sleep. I see some stuff about errors but nothing that I pick out to be the piece that is actually doing the work of the program.

I am looking at Coreutils version 9.0 from gnu/software/coreutils index.

Also I'm sure the source is pretty self-explanatory but I'm not super fluent in C yet. It's much like translating from Spanish to English.

Top answer
1 of 4
29
sleep() is a system call. It basically requests that the operating system remove the program from the list of programs that are eligible to run, and to put it back on the list after a certain amount of time has passed. If there are other programs eligible to run, they now get their shot. Otherwise, the operating system just twiddles its thumbs until some program is eligible to run. One thing to beware of: just because your program got put back on the list of programs eligible to run doesn't mean that it starts running right away. If there are other programs ahead of it in the list, it could be a while. For this reason the sleep() function really sleeps for at least as long as you requested. It could be longer. This is not a real-time environment. One final issue: if your program should receive a signal while sleeping, the operating system will put it back on the eligible list right away, and the sleep() function will fail with EINTR.
2 of 4
19
The main function inside sleep.c includes: if (xnanosleep (seconds)) die (EXIT_FAILURE, errno, _("cannot read realtime clock")); Meaning it calls the xnanosleep function for which the xnanosleep gnulib module is called. And inside the xnanosleep.c file inside main function, we have: for (;;) { /* Linux-2.6.8.1's nanosleep returns -1, but doesn't set errno when resumed after being suspended. Earlier versions would set errno to EINTR. nanosleep from linux-2.6.10, as well as implementations by (all?) other vendors, doesn't return -1 in that case; either it continues sleeping (if time remains) or it returns zero (if the wake-up time has passed). */ errno = 0; if (nanosleep (&ts_sleep, NULL) == 0) break; if (errno != EINTR && errno != 0) return -1; } Which means it's simply calling the nanosleep function. Details about the nanosleep function can be found at man nanosleep.
Top answer
1 of 8
87

Bash has a "loadable" sleep which supports fractional seconds, and eliminates overheads of an external command:

$ cd bash-3.2.48/examples/loadables
$ make sleep && mv sleep sleep.so
$ enable -f sleep.so sleep

Then:

$ which sleep
/usr/bin/sleep
$ builtin sleep
sleep: usage: sleep seconds[.fraction]
$ time (for f in `seq 1 10`; do builtin sleep 0.1; done)
real    0m1.000s
user    0m0.004s
sys     0m0.004s

The downside is that the loadables may not be provided with your bash binary, so you would need to compile them yourself as shown (though on Solaris it would not necessarily be as simple as above).

As of bash-4.4 (September 2016) all the loadables are now built and installed by default on platforms that support it, though they are built as separate shared-object files, and without a .so suffix. Unless your distro/OS has done something creative (sadly RHEL/CentOS 8 build bash-4.4 with loadable extensions deliberately removed), you should be able to do instead:

[ -z "$BASH_LOADABLES_PATH" ] &&
  BASH_LOADABLES_PATH=$(pkg-config bash --variable=loadablesdir 2>/dev/null)  
enable -f sleep sleep

(The man page implies BASH_LOADABLES_PATH is set automatically, I find this is not the case in the official distribution as of 4.4.12. If and when it is set correctly you need only enable -f filename commandname as required.)

If that's not suitable, the next easiest thing to do is build or obtain sleep from GNU coreutils, this supports the required feature. The POSIX sleep command is minimal, older Solaris versions implemented only that. Solaris 11 sleep does support fractional seconds.

As a last resort you could use perl (or any other scripting that you have to hand) with the caveat that initialising the interpreter may be comparable to the intended sleep time:

$ perl -e "select(undef,undef,undef,0.1);"
$ echo "after 100" | tclsh
2 of 8
183

The documentation for the sleep command from coreutils says:

Historical implementations of sleep have required that number be an integer, and only accepted a single argument without a suffix. However, GNU sleep accepts arbitrary floating point numbers. See Floating point.

Hence you can use sleep 0.1, sleep 1.0e-1 and similar arguments.

🌐
Linux Man Pages
man7.org › linux › man-pages › man1 › sleep.1.html
sleep(1) - Linux manual page
Pause for NUMBER seconds, where NUMBER is an integer or floating-point. SUFFIX may be 's','m','h', or 'd', for seconds, minutes, hours, days. With multiple arguments, pause for the sum of their values. --help display this help and exit --version output version information and exit · Written by Jim Meyering and Paul Eggert. Report bugs to: bug-coreutils@gnu.org GNU coreutils home page: <https://www.gnu.org/software/coreutils/> General help using GNU software: <https://www.gnu.org/gethelp/> Report any translation bugs to <https://translationproject.org/team/>
Find elsewhere
🌐
GitHub
github.com › JuliaLang › julia › issues › 12770
Accuracy and resolution of sleep() on Linux should be improved · Issue #12770 · JuliaLang/julia
August 23, 2015 - On Linux, the resolution of the function sleep() could be much better. The following test script: https://gist.github.com/ufechner7/d264fb714a551d333e6b shows an error of about 1.1 ms on my PC (core i7, 3.4 GHz, no hyper threading, Ubuntu 12.04). (Julia: 0.4.0-dev+6909). The equivalent Python script shows an error of only 0.08 ms. https://gist.github.com/ufechner7/1aa3e96a8a5972864cec · Not only the accuracy should be increased, but also the resolution. This is ...
Published   Aug 23, 2015
Top answer
1 of 8
47

The "update" to question shows some misunderstanding of how modern OSs work.

The kernel is not "allowed" a time slice. The kernel is the thing that gives out time slices to user processes. The "timer" is not set to wake the sleeping process up - it is set to stop the currently running process.

In essence, the kernel attempts to fairly distribute the CPU time by stopping processes that are on CPU too long. For a simplified picture, let's say that no process is allowed to use the CPU more than 2 milliseconds. So, the kernel would set timer to 2 milliseconds, and let the process run. When the timer fires an interrupt, the kernel gets control. It saves the running process' current state (registers, instruction pointer and so on), and the control is not returned to it. Instead, another process is picked from the list of processes waiting to be given CPU, and the process that was interrupted goes to the back of the queue.

The sleeping process is simply not in the queue of things waiting for CPU. Instead, it's stored in the sleeping queue. Whenever kernel gets timer interrupt, the sleep queue is checked, and the processes whose time have come get transferred to "waiting for CPU" queue.

This is, of course, a gross simplification. It takes very sophisticated algorithms to ensure security, fairness, balance, prioritize, prevent starvation, do it all fast and with minimum amount of memory used for kernel data.

2 of 8
36

There's a kernel data structure called the sleep queue. It's a priority queue. Whenever a process is added to the sleep queue, the expiration time of the most-soon-to-be-awakened process is calculated, and a timer is set. At that time, the expired job is taken off the queue and the process resumes execution.

(amusing trivia: in older unix implementations, there was a queue for processes for which fork() had been called, but for which the child process had not been created. It was of course called the fork queue.)

HTH!

🌐
Wikipedia
en.wikipedia.org › wiki › Sleep_(command)
sleep (command) - Wikipedia
3 weeks ago - However, sleep 5.5h (a floating point) is allowed. Consecutive executions of sleep can also be used. ... Sleep 5 hours, then sleep another 30 minutes. The GNU Project's implementation of sleep (part of coreutils) allows the user to pass an arbitrary floating point or multiple arguments, therefore sleep 5h 30m (a space separating hours and minutes is needed) will work on any system which uses GNU sleep, including Linux.
🌐
Linux Man Pages
man7.org › linux › man-pages › man3 › sleep.3.html
sleep(3) - Linux manual page
sleep() causes the calling thread to sleep either until the number of real-time seconds specified in seconds have elapsed or until a signal arrives which is not ignored.
🌐
DataFlair
data-flair.training › blogs › sleep-command-in-linux
Sleep Command in Linux - DataFlair
September 15, 2022 - The sleep command creates a dummy job that helps in delaying the execution of a command. In layman’s language, the sleep command tells the terminal to wait for the specified amount of time. There might come some scenarios where you need to delay the execution of a script, that is exactly where the sleep command comes into the picture.
🌐
Lsu
ld2015.scusa.lsu.edu › gnu_c_libs › Sleeping.html
The GNU C Library: Sleeping
The sleep function is declared in unistd.h. Resist the temptation to implement a sleep for a fixed amount of time by using the return value of sleep, when nonzero, to call sleep again. This will work with a certain amount of accuracy as long as signals arrive infrequently.
🌐
GNU
gnu.org › software › grub › manual › grub › html_node › sleep.html
GNU GRUB Manual 2.12: sleep
Sleep for count seconds. If option --interruptible is given, allow pressing ESC, F4 or holding down SHIFT to interrupt sleep. With --verbose show countdown of remaining seconds.
🌐
GitHub
github.com › coreutils › coreutils › blob › master › src › sleep.c
coreutils/src/sleep.c at master · coreutils/coreutils
/* sleep - delay for a specified amount of time. Copyright (C) 1984-2026 Free Software Foundation, Inc. · This program is free software: you can redistribute it and/or modify · it under the terms of the GNU General Public License as published by ·
Author   coreutils
🌐
nixCraft
cyberciti.biz › nixcraft › howto › bash shell › what does the sleep command do in linux?
What does the sleep command do in Linux? - nixCraft
December 13, 2022 - /bin/sleep is Linux or Unix command to delay for a specified amount of time. You can suspend the calling shell script for a specified time. For example, pause for 10 seconds or stop execution for 2 mintues. In other words, the sleep command pauses the execution on the next shell command for a given time. GNU version of sleep command supports additional options