我看到很多用法sleep 0
在我的一个客户项目中。
代码看起来像这样。
while true
...
...
sleep 0
end
阅读一些像这样的答案this https://stackoverflow.com/questions/3727420/significance-of-sleep0看起来sleep 0
有一定的意义。
我现在想知道的是,在时间片期间是否调度其他线程运行(如果它们正在等待运行)0
是 lang VM(如 ruby 或 python)的工作,或者是内核的工作。
为了让 Ruby VM 能够兑现sleep 0
就像上面链接中提到的那样。
是的,出于几个原因,首先,(mri) ruby 线程是带有附加 GVL 锁的本机线程的包装器。
本质上,当您调用 sleep 时,Ruby 所做的就是调用底层、本机、平台相关的 sleep 并释放 GVL,以便其他正在运行的线程可以获取它。所以sleep(0)
既让出其他可能正在等待执行的本机线程,又释放当前线程对 GVL 的持有,否则会阻止 Ruby VM 执行。
以下是如何从核磁共振来源中看到这一点的快速概述:
- 我们得到内核睡眠的定义https://github.com/ruby/ruby/blob/trunk/process.c#L7542 https://github.com/ruby/ruby/blob/trunk/process.c#L7542,我们看到它是在c中实现的函数
rb_f_sleep
- 接下来我们去
rb_f_sleep
并看到在单个参数的情况下它调用rb_thread_wait_for https://github.com/ruby/ruby/blob/trunk/process.c#L4379
- 去
rb_thread_wait_for
定义我们看到一个调用sleep_timeval https://github.com/ruby/ruby/blob/trunk/thread.c#L1172
-
sleep_timeval
有电话打给native_sleep https://github.com/ruby/ruby/blob/trunk/thread.c#L1111
-
native_sleep
与平台相关,并分别在 posix 和 windows 系统的 thread_pthread.c 和 thread_win32.c 中实现。在任何一种情况下,我们都会看到对GVL_UNLOCK_BEGIN
here https://github.com/ruby/ruby/blob/trunk/thread_pthread.c#L1130 and here https://github.com/ruby/ruby/blob/trunk/thread_win32.c#L307
EDIT
更准确地说:
Windows:
Windows 实现native_sleep
uses WaitForMultipleObjects
这确实产生了剩余时间片,请参见:WaitForSingleObject 是否会放弃线程的时间片? https://stackoverflow.com/questions/4170272/does-waitforsingleobject-give-up-a-threads-time-slice
Posix:
posix 实现使用pthread_cond_timedwait
,它会阻塞当前正在运行的线程。
无论哪种方式,这里要注意的主要事情是 Ruby 线程使用操作系统的底层线程阻塞机制,并通过任何睡眠调用释放 GVL,从而允许其他线程取得控制权。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)