我在我的客户项目中看到了很多sleep 0
的用法。
代码看起来像这样。
while true
...
...
sleep 0
end
通过阅读SO的一些答案,例如this,似乎sleep 0
具有一定的意义。
我现在想知道的是,在时间片0
期间调度其他线程运行(如果它们正在等待运行)是一个像Ruby或python这样的lang VM的工作,或者它是一个内核的工作。
顺便说一句,Ruby VM会尊重sleep 0
,就像在上面的链接中提到的那样。
答案 0 :(得分:6)
是的,出于几个原因,首先,(mri)ruby线程是本机线程周围的包装器,带有额外的GVL锁。
当你调用sleep时,ruby正在做的事情是调用底层的,本机的,平台相关的sleep并释放GVL,以便其他正在运行的线程可以获取它。所以sleep(0)
正在等待可能等待执行的其他本机线程以及释放当前线程在GVL上的保留,否则将阻止Ruby VM执行。
以下是关于如何从mri源中看到这一点的快速概述:
rb_f_sleep
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,允许其他线程获得控制权。