通常,在使用greenthread时,我可以将代码编写为:
def myfun():
print "in my func"
eventlet.spawn(myfunc)
eventlet.sleep(0) #then myfunc() is triggered as a thread.
但在使用money_patch(time=true)
后,我可以将代码更改为:
eventlet.monkey_patch(time=True)
eventlet.spawn(myfunc) # now myfunc is called immediately
为什么我这次不需要致电eventlet.sleep(0)
?
在我写完自己的睡眠功能后:
def my_sleep(seconds):
print "oh, my god, my own..."
并将内置时间模块的sleep attr设置为my_sleep
func,然后我发现my_sleep
func将被调用很多次,输出很多。
但我只能在eclipse中看到一个调试线程,它没有调用my_sleep
func。
因此,结论是,默认情况下会连续调用sleep函数,我认为eventlet的作者知道这一点,因此他们开发了monkey_patch()
函数。那是不是很严格?
根据@temoto的回答,CPython无法重现相同的结果。我认为我应该添加一些信息来介绍我如何找到这个有趣的东西。(为什么我第一次没有添加这个消息,导致输入这么多单词并不容易,而且我的英语不太好。^^)
当我使用eclipse远程调试openstack代码时,我发现了这一点。
在nova / network / model.py中,函数编写如下:
class NetworkInfoAsyncWrapper(NetworkInfo):
"""Wrapper around NetworkInfo that allows retrieving NetworkInfo
in an async manner.
This allows one to start querying for network information before
you know you will need it. If you have a long-running
operation, this allows the network model retrieval to occur in the
background. When you need the data, it will ensure the async
operation has completed.
As an example:
def allocate_net_info(arg1, arg2)
return call_neutron_to_allocate(arg1, arg2)
network_info = NetworkInfoAsyncWrapper(allocate_net_info, arg1, arg2)
[do a long running operation -- real network_info will be retrieved
in the background]
[do something with network_info]
"""
def __init__(self, async_method, *args, **kwargs):
self._gt = eventlet.spawn(async_method, *args, **kwargs)
methods = ['json', 'fixed_ips', 'floating_ips']
for method in methods:
fn = getattr(self, method)
wrapper = functools.partial(self._sync_wrapper, fn)
functools.update_wrapper(wrapper, fn)
setattr(self, method, wrapper)
当我第一次调试到这个函数时,执行后
self._gt = eventlet.spawn(async_method,* args,** kwargs)
回拨函数async_method
立即执行。但请记住,这是一个帖子,它应该由eventlet.sleep(0)
触发。
但是我没有找到调用sleep(0)
的代码,所以如果sleep
可能被eclipse调用,那么在现实世界(非调试世界)中,是谁触发了它?
答案 0 :(得分:1)
TL; DR:Eventlet API不需要sleep(0)
来启动绿色线程。 spawn(fun)
将在未来的某个时间开始运作,包括现在。您只应致电sleep(0)
确保立即启动,即使这样,最好使用显式同步,例如Event
或Semaphore
我无法在IPython或纯python控制台中使用CPython 2.7.6和3.4.3,eventlet 0.17.4重现此行为。所以可能是Eclipse在后台调用time.sleep
。
monkey_patch
作为运行所有(和第三方)代码并替换time.sleep -> eventlet.sleep
的快捷方式,以及类似于os
,socket
等模块的快捷方式。它与Eclipse(或其他)重复time.sleep
次呼叫无关。
但这是一个有趣的观察,谢谢。