python - Python多处理奇怪的输出
问题描述
所以我一直在尝试使用多处理优化我的程序,以便它更快地处理信息,但我得到了一些非常奇怪的结果。
代码如下:
from random import randint
import multiprocessing
import time
t = time.time()
def dice_calc(rolls):
mutex.acquire()
global wins
global loss
while rolls > 0:
dice1 = randint(1, 6)
dice2 = randint(1, 6)
if dice1+dice2 == 11 or dice1+dice2 == 7 or dice1 == dice2:
wins += 1
else:
loss += 1
rolls -= 1
mutex.release()
mutex = multiprocessing.Lock()
wins = 0
loss = 0
rolls = 1000000
if __name__ == "__main__":
p1 = multiprocessing.Process(target=dice_calc, args=(rolls/4,))
p2 = multiprocessing.Process(target=dice_calc, args=(rolls/4,))
p3 = multiprocessing.Process(target=dice_calc, args=(rolls/4,))
p4 = multiprocessing.Process(target=dice_calc, args=(rolls/4,))
p1.start()
p2.start()
p3.start()
p4.start()
p1.join()
p2.join()
p3.join()
p4.join()
print(wins)
print(loss)
#percentage = (wins / (wins + loss)) * 100
#print("Calculated percentage of a roll fulfilling requirements are:", round(percentage, 2), "%")
print(round((time.time()-t), 3))
目的是基本上找出两个骰子的总和为 7、11 或相同的机会是多少。我已经用线程模块尝试了同样的代码,效果很好(在性能方面没有真正的好处,但是嘿,它有效)
让我大吃一惊的是这个版本使用多处理的输出:
0.012
0.012
0.011
0.012
0
0
0.764
打印的前 4 个值让我很困惑。不应该有任何东西使这些输出成为可能,这些值也因运行而异。我相信它们起源于 p1、p2、p3 和 p4。
这之后的两个值不应为 0(这些值表示获胜和失败的数量,它们加起来应该是 1 000 000)
最后一个值是唯一有意义的值。它基本上只是一个计时器来检查程序运行了多长时间。
如果有人对我如何使这项工作有任何见解,我很想听听。
解决方案
您看到这些奇怪值的原因是因为您的陈述:
print(round((time.time()-t), 3))
如果您缩进该行,它将仅在名为__main__
.
发生这种情况的原因是因为在创建.Python 时Process()
,Python 在具有不同模块名称的新实例下执行该进程。因此,当函数执行完成时dice_calcs
返回并继续执行脚本,最终到达该行。
同样,您不会从您的胜利和损失变量中获得任何正确的值,因为它们存在于不同的流程中。当每个 Process 引用该变量时,它引用的是它自己的该变量的副本,而不是存在于__main__
.
要从其他模块中获取这些变量的实际值,您需要实现某种方式来跨模块进行通信。
Queue
使用模块中的 a之类的东西,queue
您可以执行以下操作:(注意:我添加的代码由 包围#######
)
from random import randint
import multiprocessing
import time
t = time.time()
def dice_calc(rolls, q):
mutex.acquire()
global wins
global loss
while rolls > 0:
dice1 = randint(1, 6)
dice2 = randint(1, 6)
if dice1+dice2 == 11 or dice1+dice2 == 7 or dice1 == dice2:
wins += 1
else:
loss += 1
rolls -= 1
########
#return wins and losses to queue
q.put((wins,loss))
########
mutex.release()
mutex = multiprocessing.Lock()
wins = 0
loss = 0
rolls = 1000000
if __name__ == "__main__":
########
#create a multiprocessing.Queue() instance that spans across Processes
q = multiprocessing.Queue()
########
p1 = multiprocessing.Process(target=dice_calc, args=(rolls/4,q))
p2 = multiprocessing.Process(target=dice_calc, args=(rolls/4, q))
p3 = multiprocessing.Process(target=dice_calc, args=(rolls/4, q))
p4 = multiprocessing.Process(target=dice_calc, args=(rolls/4, q))
p1.start()
p2.start()
p3.start()
p4.start()
########
#Get wins and losses from the queue
for _ in range(4):
item = q.get(timeout=5000)
wins = wins + item[0]
loss = loss + item[1]
########
p1.join()
p2.join()
p3.join()
p4.join()
print(wins)
print(loss)
#percentage = (wins / (wins + loss)) * 100
#print("Calculated percentage of a roll fulfilling requirements are:", round(percentage, 2), "%")
########
#Added an indent to this line
print(round((time.time()-t), 3))
########
推荐阅读
- rust - 如何从重复模式中过滤掉?
- python - 如何使用 python 输入提示窗口终止 jupyter 单元?
- flask - Flask:在登录装饰器中传递请求和其他参数
- java - Java - 杂货清单作为 JFrame
- google-tag-manager - 如果代码是通过 GTM 插入的,如何使用断点调试 JS 代码
- sql - 如何使用 JSON_DATAGUIDE 中的键获取价值(动态)
- android - 在某些设备中无法获取当前位置
- weblogic - 将我的 Bootsfaces 应用程序 Weblogic12c 迁移到 Weblogic14c
- rest - 列表的各个资源上的 REST API 和 ETag
- python - 当我运行我的python代码时,它给出“'list'对象没有属性'lower'”错误