【问题标题】:How do I place a process in the background so it does not interrupt my return?如何在后台放置一个进程,这样它就不会中断我的返回?
【发布时间】:2012-06-28 09:03:59
【问题描述】:

我的 Django 站点急需这个,但由于时间限制,我无法进行任何重大修改。这可能是最便宜的就地修改。

如果我们只关注buildrun...

  1. 现在我从 build 取回 id(或运行)。

  2. 现在所有繁重的工作都在一个单独的函数中。

'

import multiprocessing as mp
def main():
   id = get_build_id(....)
   work = mp.Process(target=heavy_build_fn)
   work.start()
   return id

如果我在 shell 中运行它(我没有在实际的 Django 应用程序上测试过它),终端不会完全结束,直到 work 进程完成它的工作。作为一个网络应用程序,我需要立即返回 id。我可以将work 放在后台而不中断吗?

谢谢。

我已阅读此How do I run another script in Python without waiting for it to finish?,但我想知道其他方法,例如,坚持使用 MP。 Popen 解决方案可能不是我真正想要的。


import multiprocessing as mp
import time

def build():
    print 'I build things'
    with open('first.txt', 'w+') as f:
        f.write('')

    time.sleep(10)
    with open('myname.txt', 'w+') as f:
        f.write('3')
    return

def main():
    build_p = mp.Process(name='build process', target=build)
    build_p.start()
    build_p.join(2)
    return 18

if __name__ == '__main__':

    v = main()
    print v
    print 'done'

控制台:

I build things
18
done
|

等待

终于

user@user-P5E-VM-DO:~$ python mp3.py
I build things
18
done
user@user-P5E-VM-DO:~$ 

【问题讨论】:

  • 处理此问题的一种典型方法是使用工作队列。根据请求填充队列并使用可能由 cron 或其他调度程序启动的单独进程来使用队列。
  • 我已经更新了我的帖子。如果你运行它,它将一直挂起,直到脚本完成。可以看到返回值,但是怕挂了。

标签: python multiprocessing


【解决方案1】:

删除join(),你可能会得到你想要的。 join() 等待进程结束后再返回。

该值将在子进程完成之前返回,但是,您的父进程将处于活动状态,直到子进程完成。不确定这是否对您来说是个问题。

这段代码:

import multiprocessing as mp
import time

def build():
    print 'I build things'
    for i in range(10):
        with open('testfile{}.txt'.format(i), 'w+') as f:
            f.write('')
            time.sleep(5)


def main():
    build_p = mp.Process(name='build process', target=build)
    build_p.start()
    return 18

if __name__ == '__main__':

    v = main()
    print v
    print 'done'

返回:

> python mptest.py
18
done
I build things

如果您需要让进程在子进程继续运行时结束,请在此处查看答案:

Run Process and Don't Wait

【讨论】:

  • 谢谢。当我像你说的那样删除join 时,它仍然需要等待孩子结束。所以它违背了目的。所以我实际上可以将build 之类的函数传递给Popen 进程吗?谢谢。
  • 现在.. 我可以看到回报。但是进程build 丢失了。它没有继续。 :(
【解决方案2】:

不,处理您想要的最简单的方法可能是使用消息代理。 Django celery 是一个很好的解决方案。它将让您排队处理并将您的 vie 权利返回给用户。然后,您的流程将按照排队的顺序执行

我相信从 Django 打开的进程与打开它们的线程相关联,因此您的视图将等待返回,直到您的进程完成

【讨论】:

  • 谢谢。问题是,这不仅仅是一个 Django 问题。这些繁重的工作是由非 Django 程序完成的。我试过thread.start_new_thread。它结束了,但我没有看到任何繁重的工作开始......
猜你喜欢
  • 2018-01-31
  • 1970-01-01
  • 2020-07-27
  • 2012-02-25
  • 2011-01-09
  • 1970-01-01
  • 2012-06-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多