我在python中有两个不同的函数,它们都有完全独立的输入和输出值。但是它们需要很长时间才能执行,最好将它们并行化。如何几乎同时执行它们?它们应该有自己的输入和输出参数。multiprocessing
套餐可能吗?
我只能找到它们在同一个队列上工作的示例。
编辑: 我现在用threading
试了一下
q = queue.Queue()
threads_list = list()
t = Thread(target=lambda fill_list, arg1: q.put(fill_list(arg1)), args=(q, list, x, y, z, xx, yy, size, stringg))
t.start()
threads_list.append(t)
for t in threads_list:
t.join()
result = q.get()
但我收到错误:
Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/lib/python3.6/threading.py", line 916, in _bootstrap_inner
self.run()
File "/usr/lib/python3.6/threading.py", line 864, in run
self._target(*self._args, **self._kwargs)
TypeError: <lambda>() takes 2 positional arguments but 9 were given
^CTraceback (most recent call last):
File "main.py", line 120, in <module>
result = q.get()
File "/usr/lib/python3.6/queue.py", line 164, in get
self.not_empty.wait()
File "/usr/lib/python3.6/threading.py", line 295, in wait
waiter.acquire()
编辑:threads_list
中只有一个线程。
谢谢
这是一个使用multiprocessing
模块的简单示例,该模块提供基于进程(而不是基于线程(的并行性:
from multiprocessing import Process, Manager
from time import sleep
def sum1(n, ret_dict):
sleep(1.0)
ret_dict['sum1'] = n + 1
def sum2(n, ret_dict):
sleep(1.0)
ret_dict['sum2'] = n + 2
def main():
manager = Manager()
ret_dict = manager.dict()
input_1 = 42
input_2 = 43
process_1 = Process(target=sum1, args=(input_1, ret_dict))
process_2 = Process(target=sum2, args=(input_2, ret_dict))
process_1.start()
process_2.start()
process_1.join()
process_2.join()
print(ret_dict)
if __name__ == "__main__":
main()
输出{'sum1': 43, 'sum2': 45}
,它应该在大约一秒内完成(而不是按顺序运行时大约两秒(。
如果可以将问题融入其中,请考虑使用multiprocessing.Pool
。
与threading
相反,multiprocessing
模块"避开"了GIL(全局解释器锁(,这是"CPython解释器用来确保一次只有一个线程执行Python字节码的机制">,用于确保线程安全,但严重降低了使用线程的效率增益。multiprocessing
基于流程的方法为此使用单独的流程,并且不会受到此问题的影响。
这适用于 CPU 密集型且进程之间没有太多通信的问题(任务队列等都可以(。
不过,有一个切线建议:很多时候人们认为他们想要多进程/多线程,他们实际上有一个 I/O 绑定场景,他们真的需要异步 I/O,不一定是多线程。对于这些情况,请查看asyncio
模块。