是否可以在子进程中运行函数而无需线程化或编写单独的文件/脚本.

wro*_*coe 59 python subprocess function popen python-multiprocessing

import subprocess

def my_function(x):
    return x + 100

output = subprocess.Popen(my_function, 1) #I would like to pass the function object and its arguments
print output 
#desired output: 101
Run Code Online (Sandbox Code Playgroud)

我只找到了使用单独脚本打开子进程的文档.有谁知道如何传递函数对象甚至是一种简单的方法来传递函数代码?

Bri*_*nna 88

我认为你正在寻找更像多处理模块的东西:

http://docs.python.org/library/multiprocessing.html#the-process-class

子进程模块用于生成进程并使用其输入/输出进行操作 - 而不是用于运行函数.

这是multiprocessing您的代码的一个版本:

from multiprocessing import Process, Queue

def my_function(q, x):
    q.put(x + 100)

if __name__ == '__main__':
    queue = Queue()
    p = Process(target=my_function, args=(queue, 1))
    p.start()
    p.join() # this blocks until the process terminates
    result = queue.get()
    print result
Run Code Online (Sandbox Code Playgroud)

  • 您可以使用`processify`装饰器作为快捷方式:https://gist.github.com/2311116 (14认同)
  • 我假设这克隆了Python解释器及其子进程的所有环境? (2认同)
  • 这是在 python 3 中工作并支持生成器函数的 processify 的一个分支。https://gist.github.com/stuaxo/889db016e51264581b50 (2认同)
  • 请注意,此代码包含一个死锁,以防您要通过队列传递非平凡的大数据-在加入进程之前始终请先执行queue.get(),否则将挂起尝试写入队列的操作,而无需读取任何内容。 (2认同)

Bri*_*ell 13

您可以使用标准的Unix fork系统调用os.fork().fork()将创建一个新进程,并运行相同的脚本.在新进程中,它将返回0,而在旧进程中,它将返回新进程的进程ID.

child_pid = os.fork()
if child_pid == 0:
  print "New proc"
else:
  print "Old proc"
Run Code Online (Sandbox Code Playgroud)

对于更高级别的库,它提供了多处理支持,为使用多个进程提供了可移植的抽象,那就是多处理模块.有一篇关于IBM DeveloperWorks的文章,使用Python进行多处理,并简要介绍了这两种技术.

  • @Devin,如果需要的话,您随时可以收回您做过的一票。 (2认同)

Eri*_*ric 7

您可以使用concurrent.futures.ProcessPoolExecutor,它不仅传播返回值,还传播任何异常:

import concurrent.futures

# must be a global function    
def my_function(x):
    if x < 0:
        raise ValueError
    return x + 100

with concurrent.futures.ProcessPoolExecutor() as executor:
    f = executor.submit(my_function, 1)
    ret = f.result()  # will rethrow any exceptions
Run Code Online (Sandbox Code Playgroud)


小智 5

Brian McKenna上面关于多处理的帖子确实很有帮助,但是如果你想沿着线程路线(与基于进程相反),这个例子将让你开始:

import threading
import time

def blocker():
    while True:
        print "Oh, sorry, am I in the way?"
        time.sleep(1)

t = threading.Thread(name='child procs', target=blocker)
t.start()

# Prove that we passed through the blocking call
print "No, that's okay" 
Run Code Online (Sandbox Code Playgroud)

您还可以使用该setDaemon(True)功能立即对线程进行后台处理.

  • 请注意,由于 GIL,Python 中的线程仅在等待事物(即非 CPU 密集型任务)时真正有用。对于 CPU 密集型任务,必须使用多处理。 (4认同)