ss2*_*025 0 python gevent greenlets
我有以下Python代码:
>>> import gevent
>>> from gevent import monkey; monkey.patch_all()
>>>
>>> def fooFn(k):
... return 'gevent_'+k
...
>>> threads = []
>>> threads.append(gevent.spawn(fooFn,'0'))
>>> threads.append(gevent.spawn(fooFn,'1'))
>>>
>>> gevent.joinall([threads[1]])
>>>
>>> print threads[1].value
gevent_1
>>> print threads[0].value
gevent_0
>>>
Run Code Online (Sandbox Code Playgroud)
如上所示,threads[0].value从中获得了适当的值fooFn。这意味着threads[0]greenlet已执行。
当我仅将threads[1]greenlet 传递给时,为什么会发生这种情况gevent.joinall?
我如何确保仅执行实际传递给的那些greenlet gevent.joinall?
你greenlets定立即当你打电话greenlet.spawn()。换句话说,它们会在您调用时立即创建并启动spawn()。这就是第一个Greenlet完成运行的原因-从您生成它们的那一刻开始,两个Greenlet都在执行,直到您从Greenlet 1查找结果的时候,两个Greenlet都已执行。
gevent.joinall()不执行greenlets-它仅告诉主线程(实际spawn编辑它们的线程)等待作为参数传入的线程完成运行。如果没有调用,joinall则有可能导致主线程在joinall()未达到greenlets的结果之前完成并退出的风险,那么谁来处理它们的结果呢?
在这里,您做了两件应该更改的操作,以使其gevents表现出所需的效果:
您joinall()是在控制台REPL中调用的,而不是从脚本中调用的。
在这里,主线程-的REPL -被保证的greenlets返回之前不能完成,因为当你调用REPL只有结束exit()
或EOF表示。但是,在没有立即用户交互的脚本中,您没有那么奢侈-当脚本中什么都没做时,执行结束。这就是为什么我们要进行调用join()以确保主线程永不退出并使您的greenlet挂起而没有父级返回的原因。
joinall()在控制台中调用是没有意义的(尽管如果要保证在下次调用Greenlet上的函数时可以从Greenlet中获得结果,这是个好主意)
spawn()如果您想确保仅执行Greenlet 1而未执行Greenlet 2,则不应该调用。相反,请阅读文档所说的内容:
要启动新的greenlet,请将目标函数及其参数传递给Greenlet构造函数,然后调用start():
>>> g = Greenlet(myfunction, 'arg1', 'arg2', kwarg1=1)
>>> g.start()或使用classmethod
spawn()这是一个执行相同操作的快捷方式:
>>> g = Greenlet.spawn(myfunction, 'arg1', 'arg2', kwarg1=1)
使用start指示绿色小工具应该在此时开始运行是一个好主意。因此:创建两个greenlet对象,并仅调用start其中一个对象以仅执行该对象。