I have a program with a GUI that needs to do some multiprocessing. The point of it is to avoid freezing the GUI, and to allow the user using some other buttons while the process is running.
I'd like then to define a method like the following:
def start_waiting(self, parent, func, args):
# Some code to execute at the end of the process
def worker(input, output):
for func, args in iter(input.get, 'STOP'):
task_queue = Queue()
done_queue = Queue()
Process(target=worker, args=(task_queue, done_queue)).start()
'Pickling an AuthenticationString object is '
TypeError: Pickling an AuthenticationString object is disallowed for security reasons
Your first example should look like this:
def start_waiting(self,parent,func,args): ...not relevant code.. self.window_waiting.show() task=Process(target=func, args=args) # This line is different. task.start() task.join()
The way you had it, it wasn't actually executing
func in a child process; it was executing it in the parent, and then passing the return value to
Process. When you called
task.start(), it would probably instantly fail, because you were passing it whatever
func returned, rather than a function object.
Note that because you're calling
start_waiting, it's probably going to block your GUI, because
start_waiting won't return until
func completes, even though its running in a child process. The only way it wouldn't block is if you're running
start_waiting in a separate thread from the GUI's event loop. You probably want something more like this:
def start_waiting(self,parent,func,args): ...not relevant code.. self.window_waiting.show() # You should interact with the GUI in the main thread only. self.task = Process(target=func, args=args) # This line is different. self.thrd = threading.Thread(target=self.start_and_wait_for_task) self.thrd.start() def start_and_wait_for_task(self): """ This runs in its own thread, so it won't block the GUI. """ self.task.start() self.task.join() # If you need to update the GUI at all here, use GLib.idle_add (see https://wiki.gnome.org/Projects/PyGObject/Threading) # This is required to safely update the GUI from outside the main thread.