[PYTHON] Sofortige Mehrfachverarbeitung

(4/5 Nachschrift) Muster, das als eingelegte temporäre Datei übergeben werden soll (9/4 postscript) Windows-kompatible Version

Erstellen Sie einen Dekorateur und werfen Sie den Prozess in den untergeordneten Prozess, ohne die vorhandene Funktion neu zu schreiben.

test.py



import os
from multiprocessing import Process, Queue

#Dekorateur
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


#Im untergeordneten Prozess ausführen und Ergebnis zurückgeben
@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)

(4/5 Nachschrift) Muster, das als eingelegte temporäre Datei übergeben werden soll Wenn die Datengröße groß ist

test2.py


import os
import pickle
from multiprocessing import Process

#Dekorateur
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

#Im untergeordneten Prozess ausführen und Ergebnis zurückgeben
@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) Windows-kompatible Version In Windows wird die Prozessstartmethode erzeugt, daher muss die vom Ziel übergebene Funktion pickle sein. Verschachtelte Funktionen können nicht eingelegt werden, daher kann diese Technik nicht verwendet werden.

Im Fall von Windows ist es überhaupt nicht interessant, aber wir werden eine Klasse erstellen.

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

#Im untergeordneten Prozess ausführen und Ergebnis zurückgeben
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

Sofortige Mehrfachverarbeitung
Multiprocessing Memorandum
Multiprocessing vs Threading