用于计算 pi 的多处理代码永远不会完成



我想计算圆周率。过程很简单:

  1. 制作一个 1x1 的正方形并在正方形中画一个圆。然后除以 4。
  2. 取两个随机值 (x, y(。
  3. 如果 x2 + y2 ≤1,则点在圆圈中。
  4. 重复上述N次。
  5. 计算内点(我称之为 K(并除以所有执行次数并乘以 4。(4 * K/N == Pi(

迭代次数越多,计算就越准确。

为了快速完成,我使用多处理库。但是多处理代码永远不会完成。怎么了?

import timeit
start = timeit.default_timer()
import random
from multiprocessing import Pool
N = 1000000
process_num = 4
def make_pi(end):
count_inbound = 0
for x 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
# Multiprocessing.
p = Pool(processes = process_num)
count_in = p.map(make_pi, [N/process_num for x in range(process_num)])
print(4*sum(count_in)/N)
# Normal.
##print(4*make_pi(N)/N)
stop = timeit.default_timer()
print(stop - start)
import time
import random
from multiprocessing import Pool
start = time.perf_counter()
N = 100000000
process_num = 96
def calc_pi(end):
count_inbound = 0
for x 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__":
multi_processing = 1
#multiprocessing code    
if multi_processing == 1: 
p = Pool()
#add with statement so that pool will close automatically. 
with p:
count_in = p.map(calc_pi, [int(N/process_num) for x in range(process_num)])
print(4*sum(count_in)/sum([int(N/process_num) for x in range(process_num)]))
#You want to do a division by sum([int(N/process_num) for x in range(process_num)]) to preserve accuracy
else: 
#normal code
print(4*calc_pi(N)/N)
finish = time.perf_counter()
print (f'Finished in {finish - start} seconds')

我在Mac上测试了相同的代码。 它工作得很好。

多进程为 0.25,单进程为 0.45。

只需更改

[N/process_num for x in range(process_num)]

[int(N/process_num for x in range(process_num)]

自我回答。

问题是需要关闭过程。

所以我只添加一行。

if __name__ == "__main__":

比我的代码确实有效!

import timeit
start = timeit.default_timer()
import random
from multiprocessing import Pool
N = 1000000
process_num = 4
def make_pi(end):
count_inbound = 0
for x 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__":
#multiprocessing code
p = Pool(processes = process_num)
count_in = p.map(make_pi, [int(N/process_num) for x in range(process_num)])
print(4*sum(count_in)/N)
#normal code
#print(4*make_pi(N)/N)
stop = timeit.default_timer()
print(stop - start)

最新更新