我想计算圆周率。过程很简单:
- 制作一个 1x1 的正方形并在正方形中画一个圆。然后除以 4。
- 取两个随机值 (x, y(。
- 如果 x2 + y2 ≤1,则点在圆圈中。
- 重复上述N次。
- 计算内点(我称之为 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)