-
-
Notifications
You must be signed in to change notification settings - Fork 226
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use of concurrent.futures.process results in BrokenProcessPool exception #111
Comments
I seem to recall |
FWIW I believe this issue breaks the documentation example of using Pyoxidizer to build Black (specifically with the latest version of black, not with version 19 as used in the example) because the latest version of black uses multiprocessing when run against a directory (e.g. |
I spent some time digging into this, and the problem is indeed the assumptions made by
That's why you're getting the I think the solution for Windows is to call The misbehavior of "spawn" is also a problem on Linux and Mac, tracked by this Python bug. You can work around it on Linux and Mac by calling So to conclude, I actually don't think this is a bug in PyOxidizer, at least not one that's feasible to fix. Instead, it's a known limitation of PyOxidizer-like tools that embed a Python interpreter in an executable (otherwise known as "freezing"), and it seems like Python intends to maintain support for this use case. So I think this is just a matter of waiting for the aforementioned bug to be fixed so I guess the one potential PyOxidizer improvement would be to document this limitation and the workaround that I mentioned, i.e. adding this to your application code: import multiprocessing
...
if __name__ == "__main__":
if "fork" in multiprocessing.get_all_start_methods():
multiprocessing.set_start_method("fork") # Handles Mac/Linux
multiprocessing.freeze_support() # Handles Windows
rest_of_your_code_here() Although that might not be safe on Mac due to the fork issue – I'm still not entirely clear on what kinds of applications it affects. |
Thank you so much for the investigation, @orn688! I definitely learned a lot about some My read of https://bugs.python.org/issue33725 indicates the macOS The It looks like all that What appears to happen on Windows is that a new instance of the current process is started with the aforementioned Theoretically, we should be able to look for I think we can do all of this automatically. We may want some config knobs to control behavior. But I'm optimistic that we can get
Applications would still need to set |
…ally pyembed is taught to call multiprocessing.set_start_method() automatically when servicing the import of the multiprocessing module. Support for this configurable behavior is wired through to Starlark. On macOS, we use the "fork" method (unlike Python itself) because we don't use framework Python builds and aren't subject to the limitation of fork() not working in framework code. multiprocessing still doesn't "just work" on Windows. That will require additional feature work. Part of #111.
I believe the I've tested this on Linux, macOS, and Windows and can confirm that processes launched with This is documented at https://pyoxidizer.readthedocs.io/en/latest/pyoxidizer_packaging_multiprocessing.html and will be released in 0.17. I would appreciate if others could test the new behavior and report back experiences. |
Successfully built my project in Windows 10 (woo!) with very little ceremony compared to other tools. Great work!
Unfortunately, I am getting the following exception when running code which makes use of
futures.ProcessPoolExecutor
:My function is:
Exception raised when called:
There is no
-B
option in my application, so what is going on there!? I suspect there is something going on with the command line options parsing here, and perhaps this has nothing to do with multiprocessing, but I don't know how to debug.The same codes runs fine on the same same system when installed via
pip
, etc. Posts elsewhere (such as here suggest that multiprocess code such as this needs to be protected with theif __name__ == '__main__'
construction, but I don't see how this could apply in this case as the code is proven to work when installed normally.Thanks for looking.
The text was updated successfully, but these errors were encountered: