Multiprocessus #

Démonstration de l'utilisation du multitraitement pour générer des données dans un processus et tracer dans un autre.

Écrit par 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)

Classe de traitement #

Cette classe trace les données qu'elle reçoit d'un tube.

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

Classe de traçage #

Cette classe utilise le multitraitement pour générer un processus pour exécuter le code de la classe ci-dessus. Une fois initialisé, il crée un canal dont une instance ProcessPlottersera exécutée dans un processus séparé.

Lorsqu'il est exécuté à partir de la ligne de commande, le processus parent envoie des données au processus engendré qui est ensuite tracé via la fonction de rappel spécifiée dans 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 générée par Sphinx-Gallery