代码看起来像这样.
while true ... ... sleep 0 end
通过阅读SO的一些答案,如this,似乎睡眠0具有一定的意义.
我现在想知道的是,在时间片0期间调度其他线程运行(如果它们正在等待运行)是像ruby或python这样的lang VM的工作,或者它是内核的工作.
按顺序,Ruby VM会像上面的链接中提到的那样尊重sleep 0.
解决方法
当你调用sleep时,ruby正在做的事情就是调用底层的,本机的,平台相关的sleep并释放GVL,以便其他正在运行的线程可以获取它.因此,sleep(0)既可以等待可能等待执行的其他本机线程,也可以释放当前线程对GVL的保持,否则将阻止Ruby VM执行.
以下是关于如何从mri源中看到这一点的快速概述:
>我们从https://github.com/ruby/ruby/blob/trunk/process.c#L7542获得内核休眠的定义,我们看到它在函数rb_f_sleep中的c中实现
>接下来我们转到rb_f_sleep并看到在单个参数的情况下它调用rb_thread_wait_for
>转到rb_thread_wait_for定义,我们看到了对sleep_timeval
的调用
> sleep_timeval可致电native_sleep
> native_sleep是平台相关的,分别在thread_pthread.c和thread_win32.c中为posix和windows系统实现.在任何一种情况下,我们都会看到对GVL_UNLOCK_BEGIN here和here的调用
编辑
更确切地说:
视窗:
native_sleep的windows实现使用WaitForMultipleObjects,它确实产生了剩余的时间片,参见:Does WaitForSingleObject give up a thread’s time slice?
POSIX:
posix实现使用pthread_cond_timedwait,它阻止当前运行的线程.
无论哪种方式,这里要注意的主要事情是Ruby线程使用操作系统的底层线程阻塞机制,并通过任何调用sleep释放GVL,允许其他线程获得控制权.