views:

1248

answers:

6

Just curious. How does actually the function Sleep() work (declared in windows.h)? Maybe not just that implementation, but anyone. With that I mean - how is it implemented? How can it make the code "stop" for a specific time? Also curious about how cin >> and those actually work. What do they do exactly?

The only way I know how to "block" something from continuing to run is with a while loop, but considering that that takes a huge amount of processing power in comparison to what's happening when you're invoking methods to read from stdin (just compare a while (true) to a read from stdin), I'm guessing that isn't what they do.

+3  A: 

The operating system schedules how processes run (which processes are eligible to run, in what order, ...). Sleep() probably issues a system call which tells the kernel “don't let me use the processor for x milliseconds”.

Bastien Léonard
Just curious. How do you make such calls yourself? If you cannot on windows because of hidden implementation, maybe a linux example?
quano
GNU/Linux conforms to Posix system calls. Posix system calls are specified as C functions, but generally they're only a wrapper around the underlying system call. If you have a look at /usr/include/asm/unistd_32.h, you'll see that there is system call for nanosleep(). It's quite probable that sleep() is implemented by calling this system call. On Windows there are system calls as well, but they are undocumented so there's virtually no reason to find out how they work.
Bastien Léonard
A: 

The answer depends on the operating system, but generally speaking, the operating system either schedules some other code to run elsewhere in another thread, or if it literally has nothing to do, it gets the CPU to wait until a hardware event occurs, which causes the CPU to jump to some code called an interrupt handler, which can then decide what code to run.

Daniel Earwicker
+11  A: 

The OS uses a mechanism called a scheduler to keep all of the threads or processes it's managing behaving nicely together.

several times per second, the computer's hardware clock interrupts the CPU, which causes the OS's scheduler to become activated. The scheduler will then look at all the processes that are trying to run and decides which one gets to run for the next time slice.

The different things it uses to decide depend on each processes state, and how much time it has had before. So if the current process has been using the CPU heavily, preventing other processes from making progress, it will make the current process wait and swaps in another process so that it can do some work.

More often, though, most processes are going to be in a wait state. For instance, if a process is waiting for input from the console, the OS can look at the processes information and see which io ports its waiting for. It can check those ports to see if they have any data for the process to work on. If they do, it can start the process up again, but if there is no data, then that process gets skipped over for the current timeslice.

as for sleep(), any process can notify the OS that it would like to wait for a while. The scheduler will then be activated even before a hardware interrupt (which is also what happens when a process tries to do a blocking read from a stream that has no data ready to be read,) and the OS makes a note of what the process is waiting for. For a sleep, the process is waiting for an alarm to go off, or it may just yield again each time it's restarted until the timer is up.

Since the OS only resumes processes after something causes it to preempt a running process, such as the process yielding or the hardware timer interrupt i mentioned, sleep() is not very accurate, how accurate depends on the OS or hardware, but it's usually on the order of one or more milliseconds.

If more accuracy is needed, or very short waits, the only option is to use the busy loop construct you mentioned.

TokenMacGuy
Good answer. +1
WolfmanDragon
+2  A: 

In short, Sleep() tells the OS to ignore the process for a while.

Joakim Elofsson
A: 

If you are looking for a more controlled way of blocking a thread/process in a multi-threaded program, have a look at Semaphores, Mutexes, CriticalSections and Events. These are all techniques used to block a process or thread (without loading the CPU via a while construct).

They essentially work off of a Wait/Signal idiom where the blocked thread is waiting and another process signals it to tell it to start again. These (at least in windows) can also have timeouts, thus providing a similar functionality to Sleep().

DeusAduro
timeout versions are available on POSIX systems as well.
TokenMacGuy
+1  A: 

'cin' uses a ton of overloaded operators. The '>>', which is usually right bit-shift, is overloaded for pretty much every type of right-hand operand in C++. A separate function is provided for each one, which reads from the console and converts the input into whichever variable type you have given. For example:

std::cin::operator>> (int &rhs);

That's not real C++ — I haven't worked with streams and overloading in a while, so I don't remember the return type or the exact order of arguments. Nevertheless, this function is called when you run cin >> an integer variable.

The exact underlying implementation depends on the operating system.

c4757p