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"屈服于任何其他线程可能已经准备好".
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收集了一些说明和参考资料.
为什么产量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)它会神奇地发挥作用。