在django视图中使用subprocess.Popen()执行python脚本

时间:2010-06-29 19:47:02

标签: python django multithreading subprocess

我看了一下,但我似乎无法解决这个问题。我想在我的django应用程序的视图中执行python脚本。我已经在django管理命令中放置了我想要执行的代码,因此可以通过命令行python manage.py command-name访问它。然后我尝试使用subprocess.Popen("python manage.py command-name",shell=True)运行此命令。

但是,此命令可能需要一些时间才能执行,因此我希望视图继续并允许脚本在后台执行。单独使用subprocess.Popen似乎会导致视图挂起,直到脚本完成,所以我尝试使用一个线程(在another SA问题之后):

class SubprocessThread(threading.Thread):
def __init__(self, c):
    self.command = c
    self.stdout = None
    self.stderr = None
    threading.Thread.__init__(self)

def run(self):
    p = subprocess.Popen(self.command,
                         shell=True,
                         stdout=subprocess.PIPE,
                         stderr=subprocess.PIPE)

    self.stdout, self.stderr = p.communicate()

然后执行它:

t = SubprocessThread("python manage.py command-name")
t.setDaemon(True)
t.start()
t.join()

但是,视图仍然挂起:光标有一个忙符号,页面上的AJAX没有加载。否则,在线程调用看起来正常完成(脚本完成之前)后,页面的html似乎加载正常并且视图中的命令。有人可以帮帮我吗?我希望脚本能够在不占用视图或页面上的AJAX调用的情况下执行并执行自己的操作。

2 个答案:

答案 0 :(得分:3)

也许你应该使用celery

  

Celery是基于任务队列/作业队列   分布式消息传递。它是   专注于实时操作

答案 1 :(得分:2)

我浪费了很多时间尝试实现类似的东西,但遇到了和你一样的问题。最终,我放弃并实现了一个beanstalk队列来处理这项工作。

http://kr.github.com/beanstalkd/

我在Django视图中的队列中放了一个id,然后有一个管理命令来运行消费者(由supervisord监视)。

使用队列意味着您可以扩展到多个使用者,并允许更好地管理负载(必要时暂停使用者而不会丢失所需的工作)。