【发布时间】:2017-12-18 19:46:23
【问题描述】:
我正在探索克莱因和延迟。在下面的示例中,我尝试使用子进程增加一个数字并通过 Future 返回它。我能够收到 Future 的回电。
问题是延迟对象永远不会调用 cb() 函数,并且对端点的请求永远不会返回。请帮我找出问题所在。
以下是我的 server.py 代码
from klein import Klein
from twisted.internet.defer import inlineCallbacks, returnValue
import Process4
if __name__ == '__main__':
app = Klein()
@app.route('/visit')
@inlineCallbacks
def get_num_visit(request):
try:
resp = yield Process4.get_visitor_num()
req.setResponseCode(200)
returnValue('Visited = {}'.format(resp))
except Exception as e:
req.setResponseCode(500)
returnValue('error {}'.format(e))
print('starting server')
app.run('0.0.0.0', 5005)
下面是Process4.py代码
from multiprocessing import Process
from concurrent.futures import Future
from time import sleep
from twisted.internet.defer import Deferred
def foo(x):
result = x+1
sleep(3)
return result
class MyProcess(Process):
def __init__(self, target, args):
super().__init__()
self.target = target
self.args = args
self.f = Future()
self.visit = 0
def run(self):
r = foo(self.visit)
self.f.set_result(result=r)
def cb(result):
print('visitor number {}'.format(result))
return result
def eb(err):
print('error occurred {}'.format(err))
return err
def future_to_deferred(future):
d = Deferred()
def callback(f):
e = f.exception()
if e:
d.errback(e)
else:
d.callback(f.result())
future.add_done_callback(callback)
return d
def get_visitor_num():
p1 = MyProcess(target=foo, args=None)
d = future_to_deferred(p1.f)
p1.start()
d.addCallback(cb)
d.addErrback(eb)
sleep(1)
return d
编辑 1
在启动进程p1之前添加回调解决了调用cb()函数的问题。但是向端点发出的http请求仍然没有返回。
【问题讨论】:
-
Twisted 和 stdlib 多处理模块不适合。请考虑安瓿。请参阅stackoverflow.com/questions/5715217/… 和stackoverflow.com/questions/1470850/… 以及关于 SO 的其他类似问题。
-
我确定必须调用
reactor.callFromThread,以便在主线程中设置结果。看看this answer I gave a while back,看看它是否有意义。您应该能够应用类似的东西。 -
感谢您的回复。请看下面我的回答。 @notorious.no,让-保罗·卡尔德隆
标签: python twisted python-multiprocessing deferred concurrent.futures