[英]run function parallel on python tornado
我目前正在tornado
框架上使用python3
(仍是初学者)进行开发,并且我想在后台运行一个函数。 更准确地说,该功能的任务是下载一个大文件(逐块),并在每个块下载后可能还要执行更多操作。 但是调用函数不应等待下载函数完成,而应继续执行。
下面是一些代码示例:
@gen.coroutine
def dosomethingfunc(self, env):
print("Do something")
self.downloadfunc(file_url, target_path) #I don't want to wait here
print("Do something else")
@gen.coroutine
def downloadfunc(self, file_url, target_path):
response = urllib.request.urlopen(file_url)
CHUNK = 16 * 1024
with open(target_path, 'wb') as f:
while True:
chunk = response.read(CHUNK)
if not chunk:
break
f.write(chunk)
time.sleep(0.1) #do something after a chunk is downloaded - sleep only as example
我已经在stackoverflow https://stackoverflow.com/a/25083098/2492068上阅读了此答案,并尝试使用它。
其实我想,如果我用@gen.coroutine
但没有yield
的dosomethingfunc
将继续无需等待downloadfunc
完成。 但是实际上行为是相同的(无论是否产生收益)-仅在downloadfunc
完成下载后才打印"Do something else
”。
我在这里想念的是什么?
为了使Tornado的异步功能受益,必须在某个时刻yielded
非阻塞函数。 由于downloadfunc
的代码全部被阻塞,因此dosomethingfunc
在调用的函数完成之前不会获得控制权。
您的代码有几个问题:
time.sleep
阻塞,使用tornado.gen.sleep
代替, urlopen
被阻止,请使用tornado.httpclient.AsyncHTTPClient
所以downloadfunc
看起来像:
@gen.coroutine
def downloadfunc(self, file_url, target_path):
client = tornado.httpclient.AsyncHTTPClient()
# below code will start downloading and
# give back control to the ioloop while waiting for data
res = yield client.fetch(file_url)
with open(target_path, 'wb') as f:
f.write(res)
yield tornado.gen.sleep(0.1)
要通过流(按块)支持来实现它,您可能需要这样做:
# for large files you must increase max_body_size
# because deault body limit in Tornado is set to 100MB
tornado.web.AsyncHTTPClient.configure(None, max_body_size=2*1024**3)
@gen.coroutine
def downloadfunc(self, file_url, target_path):
client = tornado.httpclient.AsyncHTTPClient()
# the streaming_callback will be called with received portion of data
yield client.fetch(file_url, streaming_callback=write_chunk)
def write_chunk(chunk):
# note the "a" mode, to append to the file
with open(target_path, 'ab') as f:
print('chunk %s' % len(chunk))
f.write(chunk)
现在,您可以在dosomethingfunc
调用它而不使用yield
,其余功能将继续进行。
编辑
服务器和客户端均不支持(公开)修改块大小。 您也可以查看https://groups.google.com/forum/#!topic/python-tornado/K8zerl1JB5o
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.