并发期货提交任务以非阻塞地处理池

时间:2017-02-11 02:35:20

标签: python python-2.x concurrent.futures

这个问题是Python 2特有的,使用社区维护的concurrent.futures的后端口。

我尝试使用ProcessPoolExecutor(maxWorkers简单地设置为2)并行运行两个任务。这些任务都是Python函数,我希望它们中的每一个都能在自己的进程中运行。他们不需要彼此协调(我甚至不需要知道退出状态)。我只是希望能够同时启动进程并限制在任何给定时刻并行运行的进程数。

import concurrent.futures as futures
import time


def do_stuff(name):
    for x in range(10):
        print name, x
        time.sleep(1)


pool = futures.ProcessPoolExecutor(max_workers=2)
pool.submit(do_stuff("a"))
print "a submitted!"
pool.submit(do_stuff("b"))

然而,打印

a 0 a 1 ... a 9 a submitted! b 0 b 1 ... b 9

为什么submit是阻止操作?是否存在非阻塞等效物?

以下是使用具有我想要的行为的multiprocessing库的示例。它以非阻塞方式启动每个进程,然后调用join(可能只是waitpid(2)周围的一个薄包装器)。但是,这种技术不能让我能够限制在任何给定时刻并行运行的进程数。

import multiprocessing
import time


def do_stuff(name):
    for x in range(10):
        print name, x
        time.sleep(1)


proc_a = multiprocessing.Process(target=do_stuff, args="a")
proc_b = multiprocessing.Process(target=do_stuff, args="b")
proc_a.start()
proc_b.start()
proc_a.join()
proc_b.join()

1 个答案:

答案 0 :(得分:6)

您的代码中的串行打印输出(而不是并发的)似乎是由您用于提交函数参数的错误语法引起的。应使用逗号Executor.submit()将参数与函数分开。请尝试使用此版本。

import concurrent.futures as futures
import time

def do_stuff(name):
    for x in range(10):
        print name, x
        time.sleep(1)

pool = futures.ProcessPoolExecutor(max_workers=2)
pool.submit(do_stuff, "a")
print "a submitted!"
pool.submit(do_stuff, "b")
print "b submitted!"

此外,我建议尽可能使用“with”语句来管理您的提交,因为它将确保正确关闭/关闭concurrent.futures.Executor。文件中提到了这一点。

with futures.ProcessPoolExecutor(max_workers=2) as executor:
    executor.submit(do_stuff, "a") 
    print "a submitted!"
    executor.submit(do_stuff, "b")
    print "b submitted!"