我尝试使用多进程来跨多个进程运行许多模拟;但是,据我所知,我编写的代码只使用了其中一个进程。在
更新
多亏了@PaulBecotte,我让所有的进程都能正常工作(我想);然而,多处理似乎比非多处理的运行速度慢得多。在
例如,不包括函数和类声明/实现和导入,我有:
def monty_hall_sim(num_trial, player_type='AlwaysSwitchPlayer'):
if player_type == 'NeverSwitchPlayer':
player = NeverSwitchPlayer('Never Switch Player')
else:
player = AlwaysSwitchPlayer('Always Switch Player')
return (MontyHallGame().play_game(player) for trial in xrange(num_trial))
def do_work(in_queue, out_queue):
while True:
try:
f, args = in_queue.get()
ret = f(*args)
for result in ret:
out_queue.put(result)
except:
break
def main():
logging.getLogger().setLevel(logging.ERROR)
always_switch_input_queue = multiprocessing.Queue()
always_switch_output_queue = multiprocessing.Queue()
total_sims = 20
num_processes = 5
process_sims = total_sims/num_processes
with Timer(timer_name='Always Switch Timer'):
for i in xrange(num_processes):
always_switch_input_queue.put((monty_hall_sim, (process_sims, 'AlwaysSwitchPlayer')))
procs = [multiprocessing.Process(target=do_work, args=(always_switch_input_queue, always_switch_output_queue)) for i in range(num_processes)]
for proc in procs:
proc.start()
always_switch_res = []
while len(always_switch_res) != total_sims:
always_switch_res.append(always_switch_output_queue.get())
always_switch_success = float(always_switch_res.count(True))/float(len(always_switch_res))
print '\tLength of Always Switch Result List: {alw_sw_len}'.format(alw_sw_len=len(always_switch_res))
print '\tThe success average of switching doors was: {alw_sw_prob}'.format(alw_sw_prob=always_switch_success)
结果是:
^{pr2}$但是,我尝试在total_sims = 10,000,000
上使用total_sims = 10,000,000
,这样做比使用1个进程(3分钟内返回1个进程)花费的时间要长得多。我比较它的非多处理对应项是:
def main():
logging.getLogger().setLevel(logging.ERROR)
with Timer(timer_name='Always Switch Monty Hall Timer'):
always_switch_res = [MontyHallGame().play_game(AlwaysSwitchPlayer('Monty Hall')) for x in xrange(10000000)]
always_switch_success = float(always_switch_res.count(True))/float(len(always_switch_res))
print '\n\tThe success average of not switching doors was: {not_switching}' \
'\n\tThe success average of switching doors was: {switching}'.format(not_switching=never_switch_success,
switching=always_switch_success)
通过将monty_hall_sim的return改为list comprehension,让do嫒u work将列表添加到输出队列中,然后使用输出队列返回的列表扩展main的结果列表,我的代码运行速度明显更快。让它在13秒内跑完。在
您可以尝试在一些if语句下导入“process”
编辑-你改变了一些东西,让我试着解释一下。在
输入队列中的每一条消息都会导致monty_hall_sim函数被调用,并向输出队列发送num_trial消息。在
所以你最初的实现是正确的——得到20条输出消息,发送5条输入消息。在
但是,您的功能有点错误。在
这将把函数变成一个发生器,在每个下一个调用中提供一个新的值——太好了!问题就在这里
^{pr2}$在这里,在循环的每一次传递中,都会创建一个包含新消息的新生成器。旧的被扔掉了。因此,在这里,每个输入消息只向队列中添加一个输出消息,然后将其丢弃并获取另一个输出消息。正确的写法是-
这样做将继续从生成器生成输出消息,直到它完成(在本例中生成4条消息之后)
相关问题 更多 >
编程相关推荐