我是Python新手,我只是想知道使用Web2Py是否可以轻松实现以下目标。
背景
我有一个网页表单,用户可以上传一个zip文件,webapp将处理里面的文件并显示结果。现在一切正常,但我做webapp的方式是单线程,即webapp将解压缩zip文件并逐个处理文件,并在所有文件处理时显示结果。
我使用第三方脚本来处理文件,这些文件在作业完成时不会提示任何内容。它只会在磁盘上创建结果文件。
由于每个文件至少需要2到5分钟才能处理,而且我有一个带有12个vCPU的云服务器,我现在的工作方式效率非常低。
目标:
我想让它在多线程中运行,即将所有文件放在队列中并并行处理它们。
问题:
假设最大工作数设置为12.如果用户上传的文件少于12个,则应为每个文件创建一个工作程序并并行处理它们。
我使用线程完成了这部分。如果用户想要在页面上等待结果,则结果页面将每5分钟刷新一次(或者用户可以随时返回以查看其帐户中的结果)。 webapp只是检查磁盘以查看结果文件是否存在,如果是,则只显示它。
我如何实现:
如果用户上传了超过12个文件(例如30个文件)。应创建12个工作程序,并处理前12个文件。每当工作完成处理文件时,将创建一个新工作程序从队列和进程中获取文件。有没有办法,一旦工人完成运行脚本,它就会创建一个新的工作者来运行?
由于我是Python新手(实际上是编程新手),因此我们非常感谢一种实现这一目标的简单方法。谢谢。
答案 0 :(得分:0)
由于您在第三方脚本中处理文件,因此与web2py无关。
考虑files_count
是您的应用程序需要处理的文件数。然后您可以使用以下条件:
threads_count = files_count if files_count < 12 else 12
现在threads_count
包含您能够启动的线程数,最多为12个。接下来,创建一个将由每个线程/工作者使用的队列(线程安全) ,并用文件名填充它。
from threading import Thread
from Queue import Queue, Empty
q = Queue()
for filename in filenames:
q.put(filename)
for i in xrange(threads_count):
t = Thread(target=worker, args=(q,))
t.start()
最后,由于您已拥有worker
功能,请进行必要的更改以接收q
参数。
def worker(q, ...):
try:
filename = q.get(block=False)
except Empty:
# All files have been processed.
return
您事先并不知道每个工作人员将处理多少个文件。只要一个工作人员可用,它就会立即从队列中消耗新任务,或者如果队列为空则退出。
希望它有所帮助!