python - 从多处理库中检索值
问题描述
我正在尝试使用多处理库来比较我的处理器在 1 核与 2 核上的性能。因此,我使用 1 个循环、1 个核心上的 2 个循环和 2 个核心上的 2 个循环(1 个核心/循环)来计算一个很棒的产品。问题是D1.result和D2.result的值为 0,尽管它们应该是“半/循环”的乘积。代码如下:
import random
from multiprocessing import Process as Task, freeze_support
N = 10 ** 3
l = [random.randint(2 ** 999, 2 ** 1000 - 1) for x in range(N)]
# ---------------------------------------------------------------
class Loop:
def __init__(self):
self.result=0
def boucle(self,start,end):
self.result = l[start]
for v in l[start+1:end]:
self.result = self.result*v
# ---------------------------------------------------------------
if __name__=="__main__":
print("1 Loop without multiprocessing")
A=Loop()
sta = time.time()
ra=A.boucle(0,N)
end = time.time()
print("--> Time :", end - sta)
#----------------------------------------------------------------------
print("2 Loops without multiprocessing")
B1=Loop()
B2=Loop()
sta = time.time()
rb1 = B1.boucle(0, N//2)
rb2 = B2.boucle(N//2, N)
rb = B1.result*B2.result
end = time.time()
print("--> Time :", end - sta)
if rb - A.result == 0 :
check="OK"
else :
check="fail"
print("--> Check :", check)
# ----------------------------------------------------------------------
print("2 Loops with multiprocessing")
freeze_support()
D1=Loop()
D2=Loop()
v1 = Task(target=D1.boucle, args=(0,N//2))
v2 = Task(target=D2.boucle, args=(N//2,N))
sta = time.time()
v1.start()
v2.start()
v1.join()
v2.join()
rd = D1.result*D2.result
end = time.time()
print("D1",D1.result)
print("D2",D2.result)
print("--> Time :", end - sta)
if rd - A.result == 0 :
check="OK"
else :
check="fail"
print("--> Check :", check)
这段代码的结果是:
1 Loop without multiprocessing
--> Time : 0.5025153160095215
2 Loops without multiprocessing
--> Time : 0.283463716506958
--> Check : OK
2 Loops with multiprocessing
D1 0
D2 0
--> Time : 0.2579989433288574
--> Check : fail
Process finished with exit code 0
为什么D1 0和D2 0而不是循环的结果?谢谢 !
解决方案
当显示 D1 和 D2 时,会显示此代码的问题:在多处理中,任务在分叉的进程中执行。这个过程得到了数据的副本。在每个分叉的进程中,该值都被正确计算,但它永远不会被发送回主进程。
要解决此问题,您可以:
使用共享内存来存储结果,但在这种情况下,您仅限于 C 类型。您的数字不适合 64 位(C 中的最大整数大小),所以这不是一个好的解决方案。
使用进程池,因此数据将使用队列共享,您将能够管理真正的 python 类型。
最后一个选项要求“boule”函数返回结果。
这是代码:
import random
from multiprocessing import Process as Task, freeze_support, Pool
import time
N = 10 ** 3
l = [random.randint(2 ** 999, 2 ** 1000 - 1) for x in range(N)]
# ---------------------------------------------------------------
class Loop:
def __init__(self):
self.result = 0
def boucle(self, start, end):
self.result = l[start]
for v in l[start + 1:end]:
self.result = self.result * v
return self.result
# ---------------------------------------------------------------
if __name__ == "__main__":
print("1 Loop without multiprocessing")
A = Loop()
sta = time.time()
ra = A.boucle(0, N)
end = time.time()
print("--> Time :", end - sta)
# ----------------------------------------------------------------------
print("2 Loops without multiprocessing")
B1 = Loop()
B2 = Loop()
sta = time.time()
rb1 = B1.boucle(0, N // 2)
rb2 = B2.boucle(N // 2, N)
rb = B1.result * B2.result
end = time.time()
print("--> Time :", end - sta)
if rb - A.result == 0:
check = "OK"
else:
check = "fail"
print("--> Check :", check)
# ----------------------------------------------------------------------
print("2 Loops with multiprocessing")
freeze_support()
D1 = Loop()
D2 = Loop()
pool = Pool(processes=2)
with pool:
sta = time.time()
sta = time.time()
rb1 = pool.apply_async(B1.boucle, (0, N // 2))
rb2 = pool.apply_async(B2.boucle, (N // 2, N))
v1 = rb1.get()
v2 = rb2.get()
rd = v1 * v2
end = time.time()
print("D1", D1.result)
print("D2", D2.result)
print("--> Time :", end - sta)
if rd - A.result == 0:
check = "OK"
else:
check = "fail"
print("--> Check :", check)
结果:
1 Loop without multiprocessing
--> Time : 0.3473360538482666
2 Loops without multiprocessing
--> Time : 0.18696999549865723
--> Check : OK
2 Loops with multiprocessing
D1 0
D2 0
--> Time : 0.1116642951965332
--> Check : OK
您也可以将 map 与池一起使用以取回值,但在这种情况下我没有尝试过,因为您只调用 2 个函数,并且池工作人员通过“函数包 - 请参阅 maxtaskperchild”获取任务,因此有可能只有一名工人会为自己承担这两个功能
推荐阅读
- python - Pandas 中的十进制四舍五入
- php - 如何激活 laravel
- r - A few questions about grepl and word search in a corpus
- android - NativeScript ListView:移动 1 列/平板电脑 2 列
- reactjs - 如何在我的组件中设置此状态的类型
- mongodb - MongoDB aggregation $unwind equivalent of ElasticSearch
- java - Start Service in background Service
- watson-studio - Watson Studio 在 Refine 中更改同一类型的多个列类型
- django-admin - how to initialize inline form set for admin page
- php - Content added after PHP "included" files not positioning correctly