如何使两个映射器函数并行运行?

时间:2016-10-11 19:41:20

标签: multithreading python-2.7 python-3.x multiprocessing

我在multiprocessing上阅读了这篇python文档。

但我有以下要求:

from multiprocessing import Pool
import time

def f(x):
    print(x)
    time.sleep(100000000000000);
    return x*x

def f2(x):
    print('**' + str(x) + '**')
    time.sleep(100000000000000);
    return x*x*x;
if __name__ == '__main__':
    p = Pool(5)
    print(p.map(f, [1, 2, 3]))
    print(p.map(f2,[1,2,3]))

我有一个用例,其中函数f是阻塞的(在我的情况下它会监听一个rabbitmq队列,因此它应该是阻塞的。我使用了很长时间的延迟--100000000000000来暗示无限时间阻塞)。 我在这里使用time.delay模拟了阻塞。

但需要的是我希望f2(与f不同)启动并运行并行。目前它甚至没有像f本身那样进入f2。

有人可以提供一些关于如何使f和f2并行启动的指导,尽管事实上f和f2都是阻塞的。

更新

好像我找到了办法,但感到困惑

from multiprocessing import Pool
import time

def f(x):
    print(x)
    time.sleep(100000000000000);
    return x*x

def f2(x):
    print('**' + str(x) + '**')
    time.sleep(100000000000000);
    return x*x*x;

if __name__ == '__main__':
    p = Pool(5)
    res = p.apply_async(f, [2])
    res = p.apply_async(f2,[4])
    res.get()

在重新分配res1之后它是如何工作的,甚至调用f?

1 个答案:

答案 0 :(得分:0)

您的方法不起作用,因为第一个池必须完成才能在第二个池之前打印结果。因此print类阻止第二个池开始。

我使用线程池同时启动两个包装器,并且异步获得结果。我不得不做一个循环而不是大sleep,因为python抱怨睡眠太大了。但是相同的事情。 在我的情况下,一次打印出1,2,3 1 2 3 。如果我将等待循环设置为合理的值,我甚至会得到一些正确的结果。

from multiprocessing import Pool
import concurrent.futures


import time

sleep_times = 1000000

def f(x):
    print(x)
    for i in range(sleep_times):
        time.sleep(10)
    return x*x

def f2(x):
    print('**' + str(x) + '**')
    for i in range(sleep_times):
        time.sleep(10)
    return x*x*x;

def fwrap(l):
    p = Pool(len(l))
    return(p.map(f, l))

def fwrap2(l):
    p = Pool(len(l))
    return(p.map(f2, l))

if __name__ == '__main__':
    jr = dict()
    with concurrent.futures.ThreadPoolExecutor(max_workers=2) as executor:
        jr[executor.submit(fwrap, (1, 2, 3))] = "f"
        jr[executor.submit(fwrap2, (1, 2, 3))] = "f2"

    for future in concurrent.futures.as_completed(jr):
        ident = jr[future]
        print(ident,future.result())

输出(当睡眠循环减少到1以避免等待太长时间)

1
**1**
2
**2**
**3**
3

在那里等待一段时间(被“处理时间”阻止)然后:

('f', [1, 4, 9])
('f2', [1, 8, 27])