0

I'm using the multiprocessing library from Python inside a Tkinter GUI to run real-time calculations independent from my GUI. I spawn the process in the following way

pti_process = multiprocessing.Process(target=self.pti.run_live, daemon=True,
                                      args=(self.live_path, self.settings.data))
pti_process.start()

This works fine on Linux. However, on Windows I got directly after spawning the process the following two exceptions:

TypeError: cannot pickle '_thread.lock' object
EOFError: Ran out of input

The code shown above is literally the only thing that I'm doing regarding multiprocessing. I do not use any lock. With threads works everything fine.

Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
bilaljo
  • 358
  • 1
  • 6
  • 13
  • 1
    Hard to tell the exact error without more of how your code is structured, but you should basically always keep all the GUI stuff in a single process. It's fine to do work in another process and pass the results back to the GUI, but things like windows, widgets, events, etc.. all frequently rely on being single process or even single threaded. Tkinter in particular has issues with threads, but iirc creating an event in order to activate a callback in the mainloop is specifically allowed in separate threads (not processes though). – Aaron Aug 02 '22 at 15:03
  • 1
    For example you may: create a `multiprocessing.Pool` for cpu intensive or long running tasks. Call these tasks with `map_async` or `apply_async`. Provide a `callback` function (which runs in the main process when map or apply is done), which generates an event for the gui via `event_generate`. [more on tkinter events](https://pythonguides.com/python-tkinter-events/) – Aaron Aug 02 '22 at 15:08

1 Answers1

2

Check this post out on the differences between multiprocessing on Linux and Windows.

On Windows, multiprocessing.Process does not support bound or unbound methods as targets, so you probably need to redefine self.pti.run_live as a function -- I believe this (the fact that self.pti.run_live is a method and thus is not picklable) is the source of the error, but it's a bit hard to tell without seeing more of your code.

Threads do not require picklable targets, so it makes sense that this works fine with threads instead of processes.

It's also worth noting that on Windows (as opposed to POSIX systems) processes are started with spawn rather than fork and so global state is not maintained in new processes.

I hope this helps.