使用Python Multiprocessing计算圆周率的代码无法终止,求问题排查
你的蒙特卡洛圆周率多进程代码卡住的原因及修复方案
嘿,我帮你排查出几个导致代码无法执行完毕的问题,一个个来看:
1. 缺少Windows多进程必需的入口保护
在Windows系统中,multiprocessing创建子进程时会重新导入整个主模块。如果没有if __name__ == '__main__':这个判断,子进程会再次执行p = Pool(...)的代码,进而无限创建新的子进程,最终导致程序彻底卡住,永远无法结束。这是Windows下使用多进程最容易踩的坑!
2. 传递给子进程的参数是浮点数
你用N/process_num计算每个进程要处理的次数,得到的是浮点数(比如1000000/4=250000.0),但make_pi函数里的range(end)要求end必须是整数。这个错误在多进程环境下不会直接抛出明显的报错,反而会让子进程挂起,导致整个程序停滞。应该用整数除法//来确保得到整数结果。
3. 随机数生成的潜在问题(非卡住原因,但影响精度)
默认情况下,多进程会继承主进程的随机种子,可能导致不同子进程生成重复的随机序列,影响圆周率的计算精度。建议在每个子进程里重新初始化随机种子。
修正后的完整代码
import timeit import random from multiprocessing import Pool import os N = 1000000 process_num = 4 def make_pi(end): # 子进程内重新初始化随机种子,避免重复序列 random.seed(os.urandom(4)) count_inbound = 0 for _ in range(end): the_x = random.random() the_y = random.random() if the_x**2 + the_y**2 <= 1: count_inbound += 1 return count_inbound if __name__ == '__main__': start = timeit.default_timer() # 使用整数除法确保参数是整数 p = Pool(processes=process_num) count_in = p.map(make_pi, [N // process_num for _ in range(process_num)]) print(f"近似圆周率:{4 * sum(count_in) / N}") stop = timeit.default_timer() print(f"执行时间:{stop - start}秒")
关键修改点说明
- 加上了
if __name__ == '__main__':,把主逻辑包裹起来,避免子进程重复执行创建Pool的代码 - 把
N/process_num改成N // process_num,传递整数参数给子进程 - 在
make_pi里用os.urandom(4)生成随机种子,确保每个子进程的随机序列独立
这样修改后,你的多进程代码应该就能正常执行完毕,而且计算精度也会更可靠啦!
内容的提问来源于stack exchange,提问作者Shwan
相关产品推荐
相关产品推荐

