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.
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
sleepuses 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
sleepmay 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.