Desperately in need for help here ...
I am trying to use multiprocessing in combination with decorators. I know there are some similar questions out there, however nothing seems to solve my problem.
I have the following class:
import functools
from multiprocessing import Pipe, get_context
def target(conn, fn, *args, **kwargs):
conn.send(fn(*args, **kwargs))
conn.close()
def decor(fn):
@functools.wraps(fn)
def wrapper(*args, **kwargs):
ctx = get_context("fork")
p_conn, c_conn = Pipe()
p = ctx.Process(target=target, args=(c_conn, fn, *args), kwargs=kwargs)
p.start()
ret = p_conn.recv()
p.join()
return ret
return wrapper
class MyClass:
@decor
def printer(self, string=""):
print(string)
MyClass().printer("foo")
In this scenario, I am gonna get this error:
_pickle.PicklingError: Can't pickle <function MyClass.printer at ...>: it's not the same object as __main__.MyClass.printer
I understand that the pickler complains due to the wrapper "transforming" my function so that it's not my original function anymore. To workaround it, I provide the function name to target:
def target(conn, name, *args, **kwargs):
# :name: is the name of the function
fn = ... # translation from name to fn (suggestions on how it's done are appreciated)
conn.send(fn(*args, **kwargs))
conn.close()
Now I run the program and it enters in a never ending loop of process creation. The reason is that when I call fn(*args, **kwargs) in the target, the decorator gets triggered which creates a new process to run target and so on and so forth.
How can I break the loop and have my function processed one single time?