Yes, for several reasons, first of all, (mri) ruby ββstreams are wrappers around their own streams with additional GVL blocking.
In essence, what Ruby does when you call sleep, it calls the base, native, platform-specific sleep mode and frees the GVL so that other running threads can receive it. Thus, sleep(0) both inferior to other native threads, which can wait for execution, and also release the current thread commit in the GVL, which otherwise could not force Ruby VM to execute.
Here is a brief description of how you can see this from the mri source:
- We get the Kernel sleep definition from https://github.com/ruby/ruby/blob/trunk/process.c#L7542 , which, as we see, is implemented in c in the
rb_f_sleep function - Next, we go to
rb_f_sleep and see that in the case of one argument, it calls rb_thread_wait_for - Following the
rb_thread_wait_for definition, we call sleep_timeval sleep_timeval has a call to native_sleepnative_sleep is platform dependent and is implemented in thread_pthread.c and thread_win32.c for posix and windows systems, respectively. In any case, we see GVL_UNLOCK_BEGIN calls here and here.
EDIT
More precisely:
Window:
The Windows implementation of native_sleep uses WaitForMultipleObjects , which really gives the remaining time slice, see Does WaitForSingleObject provide a stream time span?
Posix:
The posix implementation uses pthread_cond_timedwait , which blocks the current current thread.
In any case, the main attention should be paid to the fact that Ruby threads use the basic mechanisms for blocking OS threads and free GVL for any sleep call, allowing other threads to control.
source share