Multiproceso #

Demostración del uso de multiprocesamiento para generar datos en un proceso y graficar en otro.

Escrito por Robert Cimrman

import multiprocessing as mp
import time

import matplotlib.pyplot as plt
import numpy as np

# Fixing random state for reproducibility
np.random.seed(19680801)

Clase de procesamiento #

Esta clase traza los datos que recibe de una tubería.

class ProcessPlotter:
    def __init__(self):
        self.x = []
        self.y = []

    def terminate(self):
        plt.close('all')

    def call_back(self):
        while self.pipe.poll():
            command = self.pipe.recv()
            if command is None:
                self.terminate()
                return False
            else:
                self.x.append(command[0])
                self.y.append(command[1])
                self.ax.plot(self.x, self.y, 'ro')
        self.fig.canvas.draw()
        return True

    def __call__(self, pipe):
        print('starting plotter...')

        self.pipe = pipe
        self.fig, self.ax = plt.subplots()
        timer = self.fig.canvas.new_timer(interval=1000)
        timer.add_callback(self.call_back)
        timer.start()

        print('...done')
        plt.show()

Clase de trazado #

Esta clase usa multiprocesamiento para generar un proceso para ejecutar el código de la clase anterior. Cuando se inicializa, crea una tubería y una instancia de ProcessPlotterla cual se ejecutará en un proceso separado.

Cuando se ejecuta desde la línea de comandos, el proceso principal envía datos al proceso generado que luego se traza a través de la función de devolución de llamada especificada en ProcessPlotter:__call__.

class NBPlot:
    def __init__(self):
        self.plot_pipe, plotter_pipe = mp.Pipe()
        self.plotter = ProcessPlotter()
        self.plot_process = mp.Process(
            target=self.plotter, args=(plotter_pipe,), daemon=True)
        self.plot_process.start()

    def plot(self, finished=False):
        send = self.plot_pipe.send
        if finished:
            send(None)
        else:
            data = np.random.random(2)
            send(data)


def main():
    pl = NBPlot()
    for ii in range(10):
        pl.plot()
        time.sleep(0.5)
    pl.plot(finished=True)


if __name__ == '__main__':
    if plt.get_backend() == "MacOSX":
        mp.set_start_method("forkserver")
    main()

Galería generada por Sphinx-Gallery