2017-01-06 28 views
0

我想运行一系列命令(需要很长时间)。但我不想等待每个命令的完成。我怎样才能在Python中解决这个问题?Python创建一个子进程,不要等待

我看着

os.fork() 

subprocess.popen() 

不要以为这就是我所需要的。

代码

def command1(): 
    wait(10) 

def command2(): 
    wait(10) 

def command3(): 
    wait(10) 

我想打电话给

command1() 
command2() 
command3() 

无需等待。

+0

如果你使用Python 3.4+,你可以使用[asyncio subprocess](https://docs.python.org/3/library/asyncio-subprocess.html) –

+0

如果你的命令是python函数,你可以考虑线程:https://docs.python.org/2/library/threading.html。这也取决于你的意思是“我不想等待” – doomyster

+1

嗯......只是删除“等待”......对不起。 :)你有没有看过'multiprocessing'?您可以为每个命令启动一个进程。默认文档很好地解释了这一点。 –

回答

2

的最直接方式是使用Python的multiprocessing

from multiprocessing import Process 

def command1(): 
    wait(10) 
... 

call1 = Process(target=command1, args=(...)) 
call1.start() 
... 

这个模块被引入回正好以缓解控制在相同的代码库。当然使用的功能的外部流程执行的负担,即已经可以通过使用os.fork子进程来完成。多处理尽可能模拟Python自己的threading模糊界面。使用多处理而不是线程的一个直接好处是,这使得各种工作进程能够使用不同的CPU内核,实际上并行工作 - 而由于语言设计限制,有效的线程实际上仅限于一次执行一次,即使有几个可用时,也可以使用单个内核。

现在请注意,仍然存在一些特殊情况 - 特别是如果您是在网络请求中调用这些特殊功能。检查这个问题前几天的答案: Stop a background process in flask without creating zombie processes

2

使用python的多处理模块。

def func(arg1): 
    ... do something ... 

from multiprocessing import Process 
p = Process(target=func, args=(arg1,), name='func') 
p.start() 

完整的文件建立是在这里:https://docs.python.org/2/library/multiprocessing.html

编辑:

您还可以使用Python的线程模块,如果您使用了JPython/CPython的分布,可以克服GIL(全局解释锁定)在这些分布。

https://docs.python.org/2/library/threading.html

+0

你应该修正/澄清你的关于GIL的句子。 – moooeeeep

1

这个例子也许是适合你:

#!/usr/bin/env python3 

import sys 
import os 
import time 

def forked(fork_func): 
    def do_fork(): 
     pid = os.fork() 
     if (pid > 0): 
      fork_func() 
      exit(0) 
     else: 
      return pid 
    return do_fork 

@forked 
def command1(): 
    time.sleep(2) 

@forked 
def command2(): 
    time.sleep(1) 

command1() 
command2() 
print("Hello") 

你只需要使用装饰@forked您的功能。

只有一个问题:当主程序结束时,它等待子进程结束。

+0

这是一个很好的例子,但它实际上刚刚开始重新研究Python的多处理功能 - 而且如果打开它的文档,您会发现有很多事情可以使它正常工作。从“os.fork”在Windows平台上不起作用的事实开始。 – jsbueno

+0

但是,你有一个非常好的简单的例子。不管怎么说,还是要谢谢你。 – jsbueno

+0

我知道多处理模块。只有一个是跨平台的。作者提出了在通话时使用最少语法启动功能的问题。这种方式给了它。有可能在'do_fork()'内使用'multiprocessing'特性编写代码,这是更好的,我同意。但我的想法是使用装饰器轻语法,它不是'os.fork()'或'multiprocess.Process()'。 – ValeriyKr