python – gevent to Tornado ioloop – 结构代码与协同程序生成器

python – gevent to Tornado ioloop – 结构代码与协同程序生成器,第1张

概述我正在尝试转换一些相当简单的gevent代码来使用Tornado的异步工具.下面的示例代码使用ZMQ库来执行非常简单的请求 – 响应. import zmq.green as zmqdef fun(): i = zmq.Context.instance() sock = i.socket(zmq.REQ) sock.connect('tcp://localhost:90 我正在尝试转换一些相当简单的gevent代码来使用Tornado的异步工具.下面的示例代码使用ZMQ库来执行非常简单的请求 – 响应.

import zmq.green as zmqdef fun():    i = zmq.Context.instance()    sock = i.socket(zmq.REQ)    sock.connect('tcp://localhost:9005')    sock.send('Ping')    return sock.recv()

我可以在我的代码中的任何地方运行它作为fun(). .recv()调用在等待回复时阻塞,gevent中心可以调度代码的其他部分.收到值时,函数返回值.

我读了problems that can arise with these implicit returns,我想使用Tornado Ioloop来运行它(也因为我想在IPython Notebook中运行它).以下是一个选项,其中recv_future()返回包含结果的Future:

@gen.coroutinedef fun():    i = zmq.Context.instance()    sock = i.socket(zmq.REQ)    sock.connect('tcp://localhost:9005')    sock.send('Ping')    msg = yIEld recv_future(sock)    print "Received {}".format(msg[0])    raise gen.Return(msg)def recv_future(socket):    zmqstream = ZMQStream(socket)  # required for ZMQ    future = Future()    def _finish(reply):        future.set_result(reply)    zmqstream.on_recv(_finish)    return future

问题是现在fun()不是一个函数,而是一个生成器.因此,如果我需要从另一个函数调用它,我需要使用yIEld fun().但随后调用函数也变成了生成器!

构建使用Python生成器的代码的正确方法是什么?我是否必须使每个功能都成为发电机才能使其工作?如果我需要从__init __()调用其中一个函数怎么办?那还应该成为发电机吗?

解决方法

What if I need to call one of these functions from __init__()? Should
that also become a generator?

这是目前未解决的问题之一,具有产率/收益率的显式异步编程(在Python 3.3上).魔术方法不支持它们.您可以阅读Python核心开发人员关于异步编程的一些有趣想法,这些想法涉及到这个问题here.

What is the right way to structure code that uses Python generators?
Do I have to make every function a generator to make it work?
Not every function,but every function that you want to call a coroutine,and wait for that coroutine to finish before continuing. When you switch to an explicit asynchronous programming model,you generally want to go all-in with it – your entire program runs insIDe the tornado ioloop. So,with this toy example,you would just do:

from tornado.ioloop import Ioloopfrom tornado.gen import coroutinefrom tornado.concurrent import Future@gen.coroutinedef fun():    i = zmq.Context.instance()    sock = i.socket(zmq.REQ)    sock.connect('tcp://localhost:9005')    sock.send('Ping')    msg = yIEld recv_future(sock)    print "Received {}".format(msg[0])    raise gen.Return(msg)def recv_future(socket):    zmqstream = ZMQStream(socket)  # required for ZMQ    future = Future()    def _finish(reply):        future.set_result(reply)    zmqstream.on_recv(_finish)    return futureif __name__ == "__main__":    ioloop = Ioloop.instance()    ioloop.add_callback(fun)    ioloop.start() # This will run fun,and then block forever.    #ioloop.run_sync(fun) # This will start the ioloop,run fun,then stop the ioloop

看起来您可以通过IPython.kernel API访问ioloop IPython正在使用:

In [4]: from IPython.kernel.ioloop import managerIn [5]: manager.ioloop.Ioloop.instance()Out[5]: <zmq.eventloop.ioloop.ZMQIoloop at 0x4249ac8>
总结

以上是内存溢出为你收集整理的python – gevent to Tornado ioloop – 结构代码与协同程序/生成器全部内容,希望文章能够帮你解决python – gevent to Tornado ioloop – 结构代码与协同程序/生成器所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1197137.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-03
下一篇 2022-06-03

发表评论

登录后才能评论

评论列表(0条)

保存