多进程

演示使用多处理在一个过程中生成数据并在另一个过程中绘图。

由Robert Cimrman撰写

  1. import multiprocessing as mp
  2. import time
  3. import matplotlib.pyplot as plt
  4. import numpy as np
  5. # Fixing random state for reproducibility
  6. np.random.seed(19680801)

进程类

此类绘制从管道接收的数据。

  1. class ProcessPlotter(object):
  2. def __init__(self):
  3. self.x = []
  4. self.y = []
  5. def terminate(self):
  6. plt.close('all')
  7. def call_back(self):
  8. while self.pipe.poll():
  9. command = self.pipe.recv()
  10. if command is None:
  11. self.terminate()
  12. return False
  13. else:
  14. self.x.append(command[0])
  15. self.y.append(command[1])
  16. self.ax.plot(self.x, self.y, 'ro')
  17. self.fig.canvas.draw()
  18. return True
  19. def __call__(self, pipe):
  20. print('starting plotter...')
  21. self.pipe = pipe
  22. self.fig, self.ax = plt.subplots()
  23. timer = self.fig.canvas.new_timer(interval=1000)
  24. timer.add_callback(self.call_back)
  25. timer.start()
  26. print('...done')
  27. plt.show()

绘图类

此类使用多处理来生成一个进程,以运行上面的类中的代码。 初始化时,它会创建一个管道和一个ProcessPlotter实例,它将在一个单独的进程中运行。

从命令行运行时,父进程将数据发送到生成的进程,然后通过ProcessPlotter中指定的回调函数绘制:call

  1. class NBPlot(object):
  2. def __init__(self):
  3. self.plot_pipe, plotter_pipe = mp.Pipe()
  4. self.plotter = ProcessPlotter()
  5. self.plot_process = mp.Process(
  6. target=self.plotter, args=(plotter_pipe,), daemon=True)
  7. self.plot_process.start()
  8. def plot(self, finished=False):
  9. send = self.plot_pipe.send
  10. if finished:
  11. send(None)
  12. else:
  13. data = np.random.random(2)
  14. send(data)
  15. def main():
  16. pl = NBPlot()
  17. for ii in range(10):
  18. pl.plot()
  19. time.sleep(0.5)
  20. pl.plot(finished=True)
  21. if __name__ == '__main__':
  22. if plt.get_backend() == "MacOSX":
  23. mp.set_start_method("forkserver")
  24. main()

下载这个示例