睡眠0有特殊意义吗?

Noo*_*bie 6 ruby unix linux sleep

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

代码看起来像这样.

while true 
  ...
  ...
  sleep 0
end
Run Code Online (Sandbox Code Playgroud)

通过一些答案读,好喜欢这种似乎sleep 0具有一定的指导意义.

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

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

pho*_*zed 7

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

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

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

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

编辑

更确切地说:

视窗:

确实产生剩余时间片的native_sleep用法的windows实现WaitForMultipleObjects,请参阅:WaitForSingleObject是否放弃线程的时间片?

POSIX:

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

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