我在Linux环境中使用apache和modpython运行python脚本。它集成在一个允许文件处理的Web工具中。我的脚本中包含文件处理的部分可能会有很长的执行时间。在我的代码的原始版本中,脚本等待处理文件,最后它返回一些带有链接的html以下载生成的文件。
submit.html
<html>
<body>
<form enctype="multipart/form-data" action="./my_script.py/main" method="post">
<div> <input type="file" name="file"> </div>
<div> <input type="submit" value="Upload"> </div>
</body>
</html>
my_script.py
def main(file):
process(file)
return "<p> Download your file <a href='./%s'></a>", % file
def process(file)
#some file treatment here, and a resulting file is stored in current directory
我想写一个允许用户通过电子邮件接收结果文件的功能。在那种情况下,一旦他上传了他的文件,我想将他重定向到一个页面,他可以继续使用网络工具,而他的文件正在服务器端处理,因此用户不是Unix分叉。我已经使用这3个选项进行了多次测试,但我总是被运行脚本阻止。根据我的理解,多处理最适合我的情况,所以我试过这个:
my_script.py
def main(file, receiver_mail_address):
p = Process(target=process_and_email, args=(file, receiver_mail_address)
p.start()
return "<p> The resulting files will be emailed to you at %s.</p>" % receiver_mail_address
def process_and_email(file, receiver_mail_address):
#some file processing here, and emailing. these functions work perfectly as expected.
在这种情况下,我跳过了p.join()
步骤,这在python docs中说到了
&#34;阻止调用线程,直到其join()方法为的进程 调用终止或直到可选超时发生。&#34;
但在我的情况下,它仍然被阻止。这意味着我必须等到我的进程p
在到达return
语句之前结束。我怎么能这样做?
编辑:
我尝试更改为subprocess
模块。所以我将process_and_email
函数放入一个名为process_and_email.py的新文件中,并修改了主脚本:
my_script.py
def main(file, receiver_mail_address):
directory = os.path.firname(__file__)
path = os.path.join(directory, 'process_and_email.py')
subprocess.Popen(['python2.7', path, file, receiver_mail_address], shell=True)
return "<p> The resulting files will be emailed to you at %s.</p>" % receiver_mail_address
我仍然遇到同样的问题:在process_and_email.py文件完全执行之前,我无法访问return
语句。
答案 0 :(得分:3)
这种情况正在发生,因为在所有非守护进程子进程完成他们正在进行的工作之前,您的父进程不会退出。因此,在您的情况下,process_and_email
需要在脚本退出之前完成,即使main
已完成。您可以使子进程成为守护进程,这将允许父脚本立即退出,但它会在退出之前终止工作进程,这也不是您想要的。
我认为更好的选择是使用subprocess
模块生成一个单独的Python脚本来在后台进行处理。这样您的父脚本就可以退出,并使工作进程保持运行。
答案 1 :(得分:1)
Web应用程序中使用的常见模式是维护一个全局队列,例如beanstalkd,它具有一个名为beanstalkc的漂亮Python接口。然后,您可以将这些作业提交到队列,并拥有一个单独的程序/进程监视,可以对队列中的项进行排队和处理。