目录
一、概述
二、实现
1.使用apply_async方法实现
2.使用map_async方法实现(一)
3.使用map_async方法实现(二)
三、BUG
四、参考
pool:进程池,池中可以执行多任务进程
multiprocessing.Pool(processes=None, initializer=None, initargs=(), maxtasksperchild=None, context=None)
"""
参数介绍:
processes: 设置要使用的进程数量,如果 processes 为 None,则使用 os.cpu_count() 返回的值
initializer: 是每个工作进程启动时要执行的可调用对象,默认为None
maxtasksperchild: 工作进程退出之前可以完成的任务数,完成后用一个新的工作进程来替代原进程,为了释放闲置资源
context: 可被用于指定启动的工作进程的上下文
"""
pool中的任务分派方式
(1)使用该方法并行时,需要依次传入参数,这就需要借助for循环等工具
for i in range(50):
pool.apply_async(wrap, (result[i], ))
(2)用.get()返回每个进程的返回值,但我在用这个方法获取返回值的时候,运算速度并没有提高。
"""
并行方法
"""
import time
import random
def bubbleSort(iList):
'''冒泡排序 '''
time.sleep(1)
if len(iList) <= 1:
return iList
for i in range(1, len(iList)):
##外轮循环是为了确定最大的数
# print('hhh',i)
for j in range(0, len(iList) - i):
if iList[j] >= iList[j + 1]: # 比较相邻两数的大小
iList[j], iList[j + 1] = iList[j + 1], iList[j] # 将大数交换到靠后的位置
return iList
def wrap(x):
y = bubbleSort(x)
List = []
List.append(y)
print("=======>",List)
if __name__ == '__main__':
import multiprocessing
#随机生成50个序列,每个序列100个元素
result = list1 = [[0 for j in range(100)]for i in range(50)]
for i in range(0, 50):
for j in range(0, 100): # 循环随机数100位
result[i][j] = random.randint(0, 200) # num得到随机数
a = time.time()
# 4为创建子进程的个数
pool = multiprocessing.Pool(4)
for i in range(50):
pool.apply_async(wrap, (result[i], ))
pool.join()
pool.close()
print("主进程结束")
b = time.time()
time = b - a
print(time)
该方法将pool命令写在了“__main__”里。
(1)使用该方法传参数时,将iterable的每个元素作为参数,应用func函数。
(2)使用.get()返回结果,返回值是List的所有进程的结果。(单个元素的类型是输入数据的类型,仅由List类型进行包裹)
"""
并行方法
"""
import time
import random
def bubbleSort(iList):
'''冒泡排序 '''
print("i am running:")
time.sleep(1)
# List = []
if len(iList) <= 1:
return iList
for i in range(1, len(iList)):
##外轮循环是为了确定最大的数
# print('hhh',i)
for j in range(0, len(iList) - i):
if iList[j] >= iList[j + 1]: # 比较相邻两数的大小
iList[j], iList[j + 1] = iList[j + 1], iList[j] # 将大数交换到靠后的位置
return iList
def wrap(x):
y = bubbleSort(x)
print("y:",y)
if __name__ == '__main__':
import multiprocessing
#随机生成50个序列,每个序列100个元素
list = [[0 for j in range(100)]for i in range(50)]
for i in range(0, 50):
for j in range(0, 100): # 循环随机数100位
list[i][j] = random.randint(0, 200) # num得到随机数
a = time.time()
# 4为创建子进程的个数
pool = multiprocessing.Pool(4)
# for i in range(50):
# print(result[0])
result = pool.map_async(bubbleSort, list).get()
print(result)
# print(result)
pool.close()
pool.join()
print("主进程结束")
b = time.time()
time = b - a
print(time)
该方法将pool命令写在了函数里,但是注意:不管卸载哪里,都需要从“__main__”中触发并行,也就是,需要从“__main__”中运行。
"""
并行方法
"""
import random
import multiprocessing
def bubbleSort(iList):
import time
'''冒泡排序 '''
print("i am running:")
time.sleep(1)
# List = []
if len(iList) <= 1:
return iList
for i in range(1, len(iList)):
##外轮循环是为了确定最大的数
# print('hhh',i)
for j in range(0, len(iList) - i):
if iList[j] >= iList[j + 1]: # 比较相邻两数的大小
iList[j], iList[j + 1] = iList[j + 1], iList[j] # 将大数交换到靠后的位置
return iList
def wrap(x):
import time
a = time.time()
# 4为创建子进程的个数
pool = multiprocessing.Pool(4)
result = pool.map_async(bubbleSort, list).get()
pool.close()
pool.join()
print("主进程结束")
b = time.time()
time = b - a
print(time)
return result
def wrap_1(x):
y = wrap(x)
return y
def wrap_2(x, a, b):
c = a + b
print("c:",c)
y = wrap_1(x)
print("y:",y)
if __name__ == '__main__':
# 随机生成50个序列,每个序列100个元素
list = [[0 for j in range(100)] for i in range(50)]
for i in range(0, 50):
for j in range(0, 100): # 循环随机数100位
list[i][j] = random.randint(0, 200) # num得到随机数
wrap_2(list, a=1, b=2)
使用GPU运行时可能会报以下错误:
1.RuntimeError: Cannot re-initialize CUDA in forked subprocess. To use CUDA with multiprocessing, you must use the 'spawn' start method
2.RuntimeError: context has already been set
根据以上报错,在创建pool之前加入以下代码,即可成功运行
torch.multiprocessing.set_start_method( spawn , force=True)
python并行计算(完结篇):并行方法总结