Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

sleep 0 has special meaning?

I'm seeing a lot of usages of sleep 0 in my one of my client project.

The code look something like this.

while true 
  ...
  ...
  sleep 0
end

Reading through some of the answer of SO like this it seems that sleep 0 has some significance.

What I want to known now is that does scheduling for other thread to run (if they are waiting to run) during the time slice 0 is a job of a lang VM like ruby or python or it is a job of kernel.

In order word does Ruby VM would honor sleep 0 like it is mention in the above link.

like image 611
Noobie Avatar asked Apr 20 '16 19:04

Noobie


People also ask

Does time sleep 0 do anything?

The time. sleep() function takes a floating point number of seconds to sleep. If a fraction less than zero is provided, then this indicates the number of milliseconds for the calling thread to block.

What does sleep 0 do in Python?

A thread can call Sleep(0) to relinquish its quantum, thereby reducing its share of the CPU. Note, however, that this does not guarantee that other threads will run.

What does sleep 0 do in C?

According to MSDN's documentation for Sleep: A value of zero causes the thread to relinquish the remainder of its time slice to any other thread that is ready to run. If there are no other threads ready to run, the function returns immediately, and the thread continues execution.


1 Answers

Yes, for a couple of reasons, first of all, (mri) ruby threads are wrappers around native threads with an additional GVL lock.

Essentially what ruby is doing when you call sleep is calling the underlying, native, platform dependent sleep and releasing the GVL so that other running threads can acquire it. So sleep(0) is both yielding to other native threads that may be waiting to be executed as well as releasing the current thread's hold on the GVL which would otherwise keep the Ruby VM from executing.

Here's a quick rundown of how you can see this from mri source:

  1. We get the definition of Kernel sleep from https://github.com/ruby/ruby/blob/trunk/process.c#L7542, which we see is implemented in c in the function rb_f_sleep
  2. Next we go to rb_f_sleep and see that in the case of a single argument it calls rb_thread_wait_for
  3. Going to the rb_thread_wait_for definition we see a call to sleep_timeval
  4. sleep_timeval has a call to native_sleep
  5. native_sleep is platform dependent and implemented in thread_pthread.c and thread_win32.c for posix and windows systems respectively. In either case we see calls to GVL_UNLOCK_BEGIN here and here

EDIT

To be more precise:

Windows:

The windows implementation of native_sleep uses WaitForMultipleObjects which does indeed yield the remaining time slice, see: Does WaitForSingleObject give up a thread's time slice?

Posix:

The posix implementation uses pthread_cond_timedwait, which blocks the currently running thread.

Either way, the main thing to note here is that Ruby threads use the underlying thread blocking mechanisms of the OS and release the GVL with any call to sleep, allowing other threads to take control.

like image 108
photoionized Avatar answered Sep 27 '22 20:09

photoionized