继上节使用原生多进程并行运行,基于Redis作为消息队列完成了圆周率的计算,本节我们使用原生操作系统消息队列来替换Redis。
文件
使用文件进行通信是最简单的一种通信方式,子进程将结果输出到临时文件,父进程从文件中读出来。文件名使用子进程的进程id来命名。进程随时都可以通过os.getpid()
来获取自己的进程id。
# coding: utf-8
import os
import sys
import math
def slice(mink, maxk):
s = 0.0
for k in range(mink, maxk):
s += 1.0/(2*k+1)/(2*k+1)
return s
def pi(n):
pids = []
unit = n / 10
for i in range(10): # 分10个子进程
mink = unit * i
maxk = mink + unit
pid = os.fork()
if pid > 0:
pids.append(pid)
else:
s = slice(mink, maxk) # 子进程开始计算
with open("%d" % os.getpid(), "w") as f:
f.write(str(s))
sys.exit(0) # 子进程结束
sums = []
for pid in pids:
os.waitpid(pid, 0) # 等待子进程结束
with open("%d" % pid, "r") as f:
sums.append(float(f.read()))
os.remove("%d" % pid) # 删除通信的文件
return math.sqrt(sum(sums) * 8)
print pi(10000000)
输出
3.14159262176
管道pipe
管道是Unix进程间通信最常用的方法之一,它通过在父子进程之间开通读写通道来进行双工交流。我们通过os.read()和os.write()来对文件描述符进行读写操作,使用os.close()关闭描述符。
上图为单进程的管道