我正在学习Python中的多处理,并且在思考一个问题。对于共享列表(nums = mp.Manager().list
),是否有任何方法可以自动将列表拆分为所有进程,以便它不会并行计算相同的数字。
当前代码:
# multiple processes
nums = mp.Manager().list(range(10000))
results = mp.Queue()
def get_square(list_of_num, results_sharedlist):
# simple get square
results_sharedlist.put(list(map(lambda x: x**2, list_of_num)))
start = time.time()
process1 = mp.Process(target=get_square, args = (nums, results))
process2 = mp.Process(target=get_square, args=(nums, results))
process1.start()
process2.start()
process1.join()
process2.join()
print(time.time()-start)
for i in range(results.qsize()):
print(results.get())
当前行为
它计算同一个列表的平方两次
我想要的
我希望进程1和进程2并行计算nums列表1次的平方,而不需要定义分割。
您可以使函数决定需要对哪些数据执行操作。在当前的场景中,您希望您的函数根据并行工作的进程数量将平方计算工作除以它自己的工作。
要做到这一点,您需要让您的函数知道它正在处理哪个进程以及有多少其他进程与它一起工作。所以它只能处理特定的数据。所以你可以再传递两个参数给你的函数,这将给出并行运行进程的信息。即current_process
和total_process
。
如果你有一个长度能被2整除的列表,你想用两个过程计算它的平方,那么你的函数看起来像这样:
def get_square(list_of_num, results_sharedlist, current_process, total_process):
total_length = len(list_of_num)
start = (total_length // total_process) * (current_process - 1)
end = (total_length // total_process) * current_process
results_sharedlist.put(list(map(lambda x: x**2, list_of_num[start:end])))
TOTAL_PROCESSES = 2
process1 = mp.Process(target=get_square, args = (nums, results, 1, TOTAL_PROCESSES))
process2 = mp.Process(target=get_square, args=(nums, results, 2, TOTAL_PROCESSES))
我在这里做的假设是,你要处理的列表的长度是在你正在分配的多个进程中。如果不是,那么当前逻辑将留下一些没有输出的数字。
希望这能回答你的问题!
同意Jake的答案,但作为奖励:如果您使用的是multiprocessing.Pool()
,它会保留生成的多处理线程的内部计数器,因此您可以通过多处理从current_process
访问_identity
来避免使用参数来识别current_process
,如下所示:
from multiprocessing import current_process, Pool
p = current_process()
print('process counter:', p._identity[0])
更多信息从这个答案。