[PYTHON] Multitraitement instantané

(PostScript 4/5) Motif à remettre sous forme de fichier temporaire mariné (9/4 postscript) Version compatible Windows

Créez un décorateur et lancez le processus vers le processus enfant sans réécrire la fonction existante.

test.py



import os
from multiprocessing import Process, Queue

#Décorateur
def mp(func):
    def _f(*args, **kwargs):
        def _p(*args, **kwargs):
            al = list(args)
            q = al.pop()
            q.put(func(*al, **kwargs))
        queue = Queue()
        argsl = list(args)
        argsl.append(queue)
        proc = Process(target=_p, args=argsl, kwargs=kwargs)
        proc.start()
        proc.join()
        return queue.get()
    return _f


#Exécuter dans le processus enfant et renvoyer le résultat
@mp
def mp_test(a, b=None):
    return (a + b, os.getpid())

result, child = mp_test(1, 2)
print("parent: {}".format(os.getpid()))
print("child: {}".format(child)
print(result)

(PostScript 4/5) Motif à remettre sous forme de fichier temporaire mariné Lorsque la taille des données est importante

test2.py


import os
import pickle
from multiprocessing import Process

#Décorateur
def pickle_file(func):
    def _f(*args, **kwargs):
        def _p(*args, **kwargs):
            al = list(args)
            n = al.pop()
            res = func(*al, **kwargs)
            with open(n, "wb") as f:
                pickle.dump(res, f)
        tmp_name = "_tmp.pickle"
        argsl = list(args)
        argsl.append(tmp_name)
        proc = Process(target=_p, args=argsl, kwargs=kwargs)
        proc.start()
        proc.join()
        with open(tmp_name, "rb") as f:
            result = pickle.load(f)
        os.remove(tmp_name)
        return result
    return _f

#Exécuter dans le processus enfant et renvoyer le résultat
@pickle_file
def mp_test(a, b=None):
    return (a + b, os.getpid())

result, child = mp_test(1, 2)
print("parent: {}".format(os.getpid()))
print("child: {}".format(child)
print(result)

(9/4 postscript) Version compatible Windows Sous Windows, la méthode de démarrage du processus est spawn, donc la fonction passée par la cible doit être pickle. Les fonctions imbriquées ne peuvent pas être décapées, cette technique ne peut donc pas être utilisée.

Dans le cas de Windows, ce n'est pas du tout intéressant, mais nous allons créer une classe.

test_win.py



import os
import pickle
import multiprocessing as mp


class FileBasedIPC(object):
    def __init__(self, func):
        self.func = func

    def _f(self, *args, **kwargs):
        tmp_name = "_tmp.pickle"
        argsl = list(args)
        argsl.append(tmp_name)
        proc = mp.Process(target=self._p, args=argsl, kwargs=kwargs)
        proc.start()
        proc.join()
        with open(tmp_name, "rb") as f:
            result = pickle.load(f)
        os.remove(tmp_name)
        return result

    def _p(self, *args, **kwargs):
        al = list(args)
        n = al.pop()
        res = self.func(*al, **kwargs)
        with open(n, "wb") as f:
            pickle.dump(res, f)

    def __call__(self):
        return self._f

#Exécuter dans le processus enfant et renvoyer le résultat
def mp_test(a, b=None):
    return (a + b, os.getpid())

result, child = FileBasedIPC(mp_test)()(1, 2)
print("parent: {}".format(os.getpid()))
print("child: {}".format(child)
print(result)

Recommended Posts

Multitraitement instantané
mémorandum de multitraitement
multitraitement vs threading