我想同时执行f1和f2。但是下面的代码不起作用!
from multiprocessing import Pool
def f1(x):
return x*x
def f2(x):
return x^2
if __name__ == '__main__':
x1=10
x2=20
p= Pool(2)
out=(p.map([f1, f2], [x1, x2]))
y1=out[0]
y2=out[1]
答案 0 :(得分:2)
我相信您希望在代码中使用threading.Thread
和shared queue。
from queue import Queue
from threading import Thread
import time
def f1(q, x):
# Sleep function added to compare execution times.
time.sleep(5)
# Instead of returning the result we put it in shared queue.
q.put(x * 2)
def f2(q, x):
time.sleep(5)
q.put(x ^ 2)
if __name__ == '__main__':
x1 = 10
x2 = 20
result_queue = Queue()
# We create two threads and pass shared queue to both of them.
t1 = Thread(target=f1, args=(result_queue, x1))
t2 = Thread(target=f2, args=(result_queue, x2))
# Starting threads...
print("Start: %s" % time.ctime())
t1.start()
t2.start()
# Waiting for threads to finish execution...
t1.join()
t2.join()
print("End: %s" % time.ctime())
# After threads are done, we can read results from the queue.
while not result_queue.empty():
result = result_queue.get()
print(result)
上面的代码应该打印输出类似于:
Start: Sat Jul 2 20:50:50 2016
End: Sat Jul 2 20:50:55 2016
20
22
正如您所看到的,即使两个函数等待5秒钟以产生结果,它们也会并行执行,因此整体执行时间为5秒。
如果您关心什么函数将结果放入队列中,我可以看到两个解决方案,可以确定这一点。您可以创建多个队列或将结果包装在元组中。
def f1(q, x):
time.sleep(5)
# Tuple containing function information.
q.put((f1, x * 2))
为了进一步简化(特别是当你有许多函数需要处理时),你可以修饰你的函数(避免重复代码并允许没有队列的函数调用):
def wrap_result(func):
def wrapper(*args):
# Assuming that shared queue is always the last argument.
q = args[len(args) - 1]
# We use it to store the results only if it was provided.
if isinstance(q, Queue):
function_result = func(*args[:-1])
q.put((func, function_result))
else:
function_result = func(*args)
return function_result
return wrapper
@wrap_result
def f1(x):
time.sleep(5)
return x * 2
请注意,我的装饰器是匆忙编写的,其实现可能需要改进(例如,如果您的函数接受kwargs)。如果您决定使用它,则必须以相反的顺序传递您的参数:t1 = threading.Thread(target=f1, args=(x1, result_queue))
。
有点友好的建议。
“以下代码不起作用”对此问题一无所知。是否引发例外?是否会产生意想不到的结果?
阅读错误消息很重要。更重要的是 - 研究它们的意义。您提供的代码会引发TypeError
非常明显的消息:
File ".../stack.py", line 16, in <module> out = (p.map([f1, f2], [x1, x2]))
TypeError: 'list' object is not callable
这意味着Pool().map()
的第一个参数必须是callable
对象,例如函数。让我们看看该方法的文档。
将func应用于iterable中的每个元素,并在a中收集结果 返回的列表。
显然不允许将函数列表作为参数传递。
Here您可以阅读有关Pool().map()
方法的更多信息。
答案 1 :(得分:1)
我想同时执行f1和f2。但以下代码不起作用! ...
out=(p.map([f1, f2], [x1, x2]))
对代码的最小更改是将p.map()
调用替换为:
r1 = p.apply_async(f1, [x1])
out2 = f2(x2)
out1 = r1.get()
虽然如果您想要同时运行两个函数调用,那么此处不需要Pool()
,您可以手动启动一个线程/进程并use Pipe/Queue to get the result:
#!/usr/bin/env python
from multiprocessing import Process, Pipe
def another_process(f, args, conn):
conn.send(f(*args))
conn.close()
if __name__ == '__main__':
parent_conn, child_conn = Pipe(duplex=False)
p = Process(target=another_process, args=(f1, [x1], child_conn))
p.start()
out2 = f2(x2)
out1 = parent_conn.recv()
p.join()