【问题标题】:sleep 0 has special meaning?sleep 0 有什么特殊含义吗?
【发布时间】:2016-04-20 19:13:44
【问题描述】:

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

代码看起来像这样。

while true 
  ...
  ...
  sleep 0
end

通读this等SO的一些答案,sleep 0似乎有一定的意义。

我现在想知道的是,在时间片0 期间调度其他线程运行(如果它们正在等待运行)是 ruby​​ 或 python 之类的语言 VM 的工作,或者它是内核。

Ruby VM 会像上面链接中提到的那样尊重sleep 0

【问题讨论】:

    标签: ruby linux unix sleep


    【解决方案1】:

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

    本质上,当您调用 sleep 时,ruby 所做的是调用底层的、本机的、平台相关的 sleep 并释放 GVL,以便其他正在运行的线程可以获取它。所以sleep(0) 既让步给其他可能正在等待执行的本机线程,也释放当前线程对 GVL 的持有,否则会阻止 Ruby VM 执行。

    以下是您如何从 mri 源中看到这一点的简要说明:

    1. 我们从https://github.com/ruby/ruby/blob/trunk/process.c#L7542得到Kernel sleep的定义,我们看到是在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 依赖于平台,分别在 posix 和 windows 系统的 thread_pthread.c 和 thread_win32.c 中实现。在任何一种情况下,我们都会看到对 GVL_UNLOCK_BEGIN herehere 的调用

    编辑

    更准确地说:

    窗口:

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

    正则化:

    posix 实现使用pthread_cond_timedwait,它阻塞了当前正在运行的线程。

    无论哪种方式,这里要注意的主要一点是 Ruby 线程使用操作系统的底层线程阻塞机制,并通过任何睡眠调用释放 GVL,从而允许其他线程进行控制。

    【讨论】:

    • 只是澄清一下,话虽如此,编写该代码块的人不太可能真的试图做我描述的事情,所以我非常怀疑那些睡眠调用是否真的会有用。事实上,任何时候只要有 ruby​​ 应用程序代码调用睡眠,我就很可能会说这是代码异味(尽管并非一直如此)。
    • 很好的答案。你熟悉Ruby Cross Reference吗?这是探索 MRI 源的绝佳方式。
    • @Jordan:很棒的资源,看起来很像 LXR,谢谢你的信息!
    • 是的,它是由 LXR 生成的!
    • @Jordan:哈,刚刚看到This page was automatically generated by the 0.9.9 LXR engine. :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-06-23
    • 2016-04-01
    • 2012-11-25
    • 1970-01-01
    • 2010-12-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多