Skip to content
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

Pyinstaller multiprocessing name of process is always "MainProcess" #3957

Closed
Indiana3714 opened this issue Dec 31, 2018 · 13 comments
Closed
Assignees
Labels
area:bootloader Caused be or effecting the bootloader platform:Windows Python:2

Comments

@Indiana3714
Copy link

Here's my test code (py 2.7 on Windows):

import multiprocessing

print multiprocessing.current_process().name
print type(multiprocessing.current_process())
print type(multiprocessing.current_process().name)

def main():
    pass

if __name__ == "__main__":
    multiprocessing.freeze_support()
    p = multiprocessing.Process(target=main, name="My Child Process")
    p.start()

Without compiling, the code works fine as it prints out

MainProcess
<class 'multiprocessing.process._MainProcess'>
<type 'str'>
My Child Process
<class 'multiprocessing.process._MainProcess'>
<type 'str'>

After using pyinstaller on it, unfortunately it will always default to "MainProcess". Result as follows:

MainProcess
<class 'multiprocessing.process._MainProcess'>
<type 'str'>
MainProcess
<class 'multiprocessing.process._MainProcess'>
<type 'str'>
@htgoebel
Copy link
Member

htgoebel commented Jan 2, 2019

Are you using --onefile mode? Please try --onedir mode.
This might ne an issue with the freeze_support. Please try Python 3.x

@htgoebel htgoebel added the area:bootloader Caused be or effecting the bootloader label Jan 2, 2019
@htgoebel
Copy link
Member

htgoebel commented Jan 2, 2019

Please also state wich exact version of PyInstaller you are using. Please try the current development head.

@htgoebel htgoebel self-assigned this Jan 2, 2019
@Indiana3714
Copy link
Author

Indiana3714 commented Jan 2, 2019

@htgoebel I'm using pyinstaller 3.4 on python 2.7. Using it in the regular mode with the folder? Not one single file.exe. I tried using it on python 3.6 but it was kind of tricky to have it set to compile under python 3.6 by default instead of 2.7

@Indiana3714
Copy link
Author

Indiana3714 commented Jan 4, 2019

Please also state wich exact version of PyInstaller you are using. Please try the current development head.

PyInstaller: 3.5.dev0+1844d69f5 version still has the same issue

@htgoebel
Copy link
Member

htgoebel commented Jan 7, 2019

Please try putting multiprocessing.freeze_support() just after the import multiprocesseing

@Indiana3714
Copy link
Author

@htgoebel Doesn't work:

MainProcess
<class 'multiprocessing.process.MainProcess'>
<type 'str'>
Traceback (most recent call last):
File "githubexamplefile.py", line 2, in
File "multiprocessing_init
.py", line 145, in freeze_support
File "multiprocessing\forking.py", line 337, in freeze_support
File "multiprocessing\forking.py", line 381, in main
File "pickle.py", line 1384, in load
File "pickle.py", line 864, in load
File "pickle.py", line 1096, in load_global
File "pickle.py", line 1132, in find_class
AttributeError: 'module' object has no attribute 'main'
[4684] Failed to execute script githubexamplefile

Press Enter or Esc to close console...

@jordanjuras
Copy link

Please try putting multiprocessing.freeze_support() just after the import multiprocesseing

This fixed the described issue for me.

Note: I had put multiprocessing.freeze_support() immediately following the main definition for this python script, but new windows/processes were kicked off one after the next.

@Indiana3714
Copy link
Author

Issue still there when I'm using Python 3.7.4 now.

@olbermann
Copy link

I had very similar problems and was able to get rid of the AttributeError ... Failed to execute script...
by moving the target function to a different module and importing it into the script.

@Ratgor
Copy link

Ratgor commented Dec 5, 2019

Python 3.5, PyInstaller 3.5
Same issue
Fixed by putting multiprocessing.freeze_support() before the first call of multiprocessing inside a function, not "immediately after" import multiprocessing (attribute error).

@Legorooj Legorooj assigned htgoebel and unassigned htgoebel Feb 26, 2020
@migueldingli1997
Copy link

migueldingli1997 commented Aug 16, 2020

Any progress on this? I'm experiencing this on Mac OS where a new process also named __main__ gets created when I start a new process. In my case the workaround I used is the following, where start() is the rest of my program:

if __name__ == '__main__':
    multiprocessing.freeze_support()
    if 'main_started' not in os.environ:
        os.environ['main_started'] = ''
        start()

@juanzt
Copy link

juanzt commented Jan 24, 2021

On MacOS Big Sur, fixed as htgoebel suggested:

import multiprocessing
multiprocessing.freeze_support()

It seems critical that freeze_support() is called immediately after the import.

PickledChair added a commit to PickledChair/YukkuLips that referenced this issue Mar 7, 2021
Python の公式ドキュメントでは、Windows 以外では freeze_support()
の呼び出しは効果がないと記載されている。しかし、macOS Big Sur 11.2.2,
Python 3.9.1, PyInstaller 4.2 において、メインプロセスが多重に
呼び出される現象が発生し、その回避策として PyInstaller リポジトリの
Issue にて freeze_support() を呼ぶことが有効だと報告されていた。
cf. pyinstaller/pyinstaller#3957
@rokm
Copy link
Member

rokm commented Jun 11, 2021

Using multiprocessing.freeze_support() is not a work-around - it is the proper way of making multiprocessing work with frozen applications.

It allows PyInstaller to insert a hook that handles process spawning in the frozen application. This works differently than in unfrozen mode, because there's no python(.exe) executable involved, and so the frozen application's executable needs to handle being ran multiple times with different multiprocessing-specific arguments. The PyInstaller's hook effectively scans sys.argv for multiprocessing-specific arguments and if present, handles the further execution - so the code in those auxiliary and worker processes doesn't go beyond the multiprocessing.freeze_support() call.

This is why omitting this call results in infinite process spawning loop; as each spawned auxiliary or worker process thinks it is main process, and executes main code, and therefore eventually tries to use multiprocessing again, which results in another set of auxiliary and worker processes being spawned...

And this is why you should make the call to multiprocessing.freeze_support() "as soon as possible":

  • before you run any "main" code, such as command-line parsing (because you don't want to handle command line from auxiliary processes) or UI construction (because you don't want that in auxiliary and your worker processes)
  • after any structures (classes, functions) that are used in your processes are defined (as calling it before will result in worker processes lacking those definitions, leading to error).

@rokm rokm closed this as completed Jun 11, 2021
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Nov 16, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area:bootloader Caused be or effecting the bootloader platform:Windows Python:2
Projects
None yet
Development

No branches or pull requests

8 participants