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