2

Since some languages don't offer mutex lock, one will need to build it by one's self. I usually write some code like this: (pseudo-C++, just to let you know what I mean. I'm not sure whether my writing is correct as I haven't written C++ code in years)

oldval = 0;
newval = 1;
//suggest there was a Compare And Set operation that make only one thread return true,if no CAS operation , call any other language module that can offer a cas instead
while (!CAS(*somepointer,oldval,newval)) {
     //lock failed
     sleep(1000); //sleep one second or some value really depend on what you are doing.
}
//lock succeed, do something....
*somepointer = oldval; //release lock.

Obviously sleep will lower the speed of processing, but I used to worry about, if sleep is discarded... wouldn't threads switching too frequently and lower the performance? Now that I think deeper, how is sleep implemented? If they do something like this...

expired = getCurrentTime() + sleepTime;
while (getCurrentTime() < expired) { }

... this would only get things worse.

Now I think sleep should only be used if I really need to suspend the thread for a while, so maybe my case is just wrong.

obataku
  • 29,212
  • 3
  • 44
  • 57
Max
  • 7,957
  • 10
  • 33
  • 39
  • On Unix, that would sleep for 1000 seconds; you must be working on Windows, I think. – Jonathan Leffler Sep 16 '12 at 01:03
  • 8
    So you have a language with no synchronization primitives but with atomic CAS? Tell me more about that language... –  Sep 16 '12 at 01:03
  • 3
    @Max the implementation of `sleep` you hypothesize is very unlikely; that is known as busy-waiting, and is likely only done for very small sleep periods. Generally, `sleep` suspends the thread and talks to the underlying scheduling mechanism to yield several time slices. – obataku Sep 16 '12 at 01:05
  • 1
    See http://stackoverflow.com/questions/4911739/how-does-sleep-work. – nneonneo Sep 16 '12 at 01:07
  • Languages do not provide synchro mechanisms, operating systems do. Like Vlad says, it's very strange for a language to provide CPU-specific atomic operations but no kernel interfaces for system calls. – Martin James Sep 16 '12 at 01:10
  • @VladLazarenkol,if u can call extended module write by other languages ,cas wouldn't be a problem. – Max Sep 16 '12 at 01:15
  • @MartinJames: Some language *do* provide synchronization mechanisms. C and C++ don't (although the 2011 C standard does include add threading to the standard library). – Keith Thompson Sep 16 '12 at 02:41
  • @KeithThompson - such support is provided by OS calls, nicely wrapped up. – Martin James Sep 16 '12 at 08:33
  • @VladLazarenko `CAS` may be available as a CPU instruction like `LOCK:CMPXCHG` on x86 (even `XCHG` can be utilized for this purpose) regardless of the OS facilities. – Alexey Frunze Sep 16 '12 at 08:34
  • I would suggest to do 2 things: repeating `CAS` a number of times before doing `sleep()` & varying the number of repetitions for `CAS` and milliseconds for `sleep()` every time. This will help avoiding [livelocks](http://en.wikipedia.org/wiki/Deadlock#Livelock) and improve performance. – Alexey Frunze Sep 16 '12 at 08:40

1 Answers1

3

sleep() and related functions make a system call to the OS which requests that the OS wake up the process in a set amount of time. The OS may wake the process sooner in certain cases (e.g. receipt of a signal/exception), but the process will otherwise get zero CPU usage during the wait.

If the OS finds that all processes are sleeping (or blocked on some kind of timeout), it can go to sleep itself by using a hardware-specific instruction to sleep the processor until an interrupt (e.g. clock interrupt, DMA interrupt, etc.) is received.

OS-provided synchronization primitives work similarly. For example, asking to lock a mutex results in a system call that puts the thread to sleep until the mutex is unlocked; the OS knows that the mutex is unlocked since the unlock must also go through a system call.

Using sleep uses a lot less CPU compared to a simple busy-wait loop. However, your OS probably provides at least some synchronization primitives (even embedded systems frequently provide these if they support threads in any way), such as semaphores or locks. You should try to find out if your OS provides these functions before trying to roll your own; your application will have better performance and responsiveness if you use OS-provided synchronization primitives.

Important note: If you are developing on a bare-metal embedded platform, the library sleep may in fact be a busy wait (like it is on e.g. Arduino), since there's no OS scheduler to put threads to sleep. In this case, if minimizing processor usage is important (e.g. to reduce power consumption), you will need to find a processor-specific method of suspending the CPU if your library doesn't provide one.

nneonneo
  • 171,345
  • 36
  • 312
  • 383