睡眠0有特殊意义吗?

时间:2016-04-20 19:13:45

标签: ruby linux unix sleep

我在我的客户项目中看到了很多sleep 0的用法。

代码看起来像这样。

while true 
  ...
  ...
  sleep 0
end

通过阅读SO的一些答案,例如this,似乎sleep 0具有一定的意义。

我现在想知道的是,在时间片0期间调度其他线程运行(如果它们正在等待运行)是一个像Ruby或python这样的lang VM的工作,或者它是一个内核的工作。

顺便说一句,Ruby VM会尊重sleep 0,就像在上面的链接中提到的那样。

1 个答案:

答案 0 :(得分:6)

是的,出于几个原因,首先,(mri)ruby线程是本机线程周围的包装器,带有额外的GVL锁。

当你调用sleep时,ruby正在做的事情是调用底层的,本机的,平台相关的sleep并释放GVL,以便其他正在运行的线程可以获取它。所以sleep(0)正在等待可能等待执行的其他本机线程以及释放当前线程在GVL上的保留,否则将阻止Ruby VM执行。

以下是关于如何从mri源中看到这一点的快速概述:

  1. 我们从https://github.com/ruby/ruby/blob/trunk/process.c#L7542得到了内核睡眠的定义,我们看到它在函数rb_f_sleep
  2. 中的c中实现
  3. 接下来我们转到rb_f_sleep并查看在单个参数的情况下,它会调用rb_thread_wait_for
  4. 转到rb_thread_wait_for定义,我们看到了对sleep_timeval
  5. 的调用
  6. sleep_timeval打电话给native_sleep
  7. native_sleep是平台相关的,分别在thread_pthread.c和thread_win32.c中为posix和windows系统实现。在任何一种情况下,我们都会看到对GVL_UNLOCK_BEGIN herehere
  8. 的来电

    修改

    更确切地说:

    视窗:

    native_sleep的Windows实现使用WaitForMultipleObjects确实产生剩余时间片,请参阅:Does WaitForSingleObject give up a thread's time slice?

    Posix的:

    posix实现使用pthread_cond_timedwait,它阻止当前运行的线程。

    无论哪种方式,这里需要注意的主要事情是Ruby线程使用操作系统的底层线程阻塞机制,并通过任何调用sleep来释放GVL,允许其他线程获得控制权。