Multiprozess #

Demo der Verwendung von Multiprocessing zum Generieren von Daten in einem Prozess und zum Plotten in einem anderen.

Geschrieben von 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)

Verarbeitungsklasse #

Diese Klasse zeichnet Daten, die sie von einer Pipe empfängt.

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()

Zeichenklasse #

Diese Klasse verwendet Multiprocessing, um einen Prozess zum Ausführen von Code aus der obigen Klasse zu erzeugen. Wenn es initialisiert wird, erstellt es eine Pipe und eine Instanz ProcessPlotterdavon wird in einem separaten Prozess ausgeführt.

Bei Ausführung über die Befehlszeile sendet der übergeordnete Prozess Daten an den erzeugten Prozess, die dann über die in angegebene Callback-Funktion gezeichnet werden 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()

Galerie generiert von Sphinx-Gallery