一个threading.Thread如何在Python中产生其余的量子?

Tom*_*ure 41 python multithreading yield

我有一个线程正在轮询一块硬件.

while not hardware_is_ready():
    pass
process_data_from_hardware()
Run Code Online (Sandbox Code Playgroud)

但是还有其他线程(和进程!)可能有事情要做.如果是这样,我不想每次其他指令都烧掉cpu检查硬件.自从我处理线程以来已经有一段时间了,当我这样做时它不是Python,但我相信大多数线程库都有一个yield函数或某些东西允许线程告诉调度程序"给其他线程一个机会".

while not hardware_is_ready():
    threading.yield()          # This function doesn't exist.
process_data_from_hardware()
Run Code Online (Sandbox Code Playgroud)

但我在线程文档中找不到任何类似的引用.Python确实有一个yield声明,但我很确定这完全是另一回事(与生成器有关).

在这做什么是正确的?

Ale*_*lli 68

time.sleep(0)足以产生控制 - 不需要使用正ε.实际上,time.sleep(0)MEANS"屈服于任何其他线程可能已经准备好".

  • 这是在某处记录的吗?我认为这可能是真的 - 我已经在其他语言中看到过 - 但我在Python文档中找不到它. (4认同)
  • 例如,http://docs.python.org/library/sched.html"delayfunc也将在每个事件运行后使用参数0调用,以允许其他线程有机会在多线程应用程序中运行." (delayfunc通常是time.sleep这里).我同意如果在模块时间内更直接地记录它会更好;-) (4认同)
  • Windows用户:设置为0对我不起作用,time.sleep(0.0001)没有. (3认同)

S.L*_*ott 13

阅读Global Interpreter Lock(GIL).

例如:http://jessenoller.com/2009/02/01/python-threads-and-the-global-interpreter-lock/

另外:http://www.pyzine.com/Issue001/Section_Articles/article_ThreadingGlobalInterpreter.html

如果必须执行忙等待(例如,轮询设备),请在代码中执行此操作.

time.sleep( 0.0001 )
Run Code Online (Sandbox Code Playgroud)

这将产生线程调度程序.

另外,我在http://homepage.mac.com/s_lott/iblog/architecture/C551260341/E20081031204203/index.html收集了一些说明和参考资料.

  • 所有三个链接似乎都已损坏。 (3认同)
  • 我不是专家,但我在GIL上读过一些内容.你能给我一个提示,特别是这个问题吗?我现在要用'time.sleep(epsilon)`,但它有点令人不满意,不是吗?没有任何特定的间隔我想睡觉. (2认同)

mic*_*l_s 6

为什么产量time.sleep(0)可能不够:

我遇到了类似的问题,最终time.sleep(0)在所有情况下都没有工作而time.sleep(0.0001)工作。就我而言,我使用标准的 vanilla cpython - 可以在 python.org 上找到。sleep(0)查看 C 代码中 sleep 函数的实现,可以发现和 的调用之间存在微小差异sleep(something_other_than_null)

查看timemodule.c 中的 pysleep你会发现在第一种情况下

if (ul_millis == 0 || !_PyOS_IsMainThread()) {
  Py_BEGIN_ALLOW_THREADS
  Sleep(ul_millis);
  Py_END_ALLOW_THREADS
  break;
}
Run Code Online (Sandbox Code Playgroud)

叫做。“允许线程”释放 GIL,Sleep(0)在这种情况下相当于std::this_thread::yield(),之后再次声明 GIL。在处理非零值的代码中,除了实际的睡眠/等待之外,还有对PyErr_CheckSignals的额外调用- 正如其文档中所述“检查信号是否已发送到进程,如果是,则调用相应的信号处理程序”。这可以解释为什么在某些情况下使用硬件时 atime.sleep(0)是不够的。所以这可能是 cpython 实现方面的一个失误。这就是为什么time.sleep(0.0001)它会神奇地发挥作用。