This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author orlenko
Recipients jnoller, orlenko
Date 2009-02-06.02:00:29
SpamBayes Score 8.937295e-15
Marked as misclassified No
Message-id <1233885632.9.0.0484597105973.issue5162@psf.upfronthosting.co.za>
In-reply-to
Content
I think I've found a small bug with multiprocessing package on 
Windows. If you try to start a multiprocessing.Process from a Python- 
based Windows service, the child process will fail to run. When 
running the parent process as a regular Python program, everything 
works as expected. 
I've tracked the problem down to how main_path is prepared in 
multiprocessing.forking.get_preparation_data() (lines 370-377): 
def get_preparation_data(name): 
    [...skipped a few lines...] 
    if not WINEXE: 
        main_path = getattr(sys.modules['__main__'], '__file__', None) 
        if not main_path and sys.argv[0] not in ('', '-c'): 
            main_path = sys.argv[0] 
        if main_path is not None: 
            if not os.path.isabs(main_path) and \ 
                                      process.ORIGINAL_DIR is not 
None: 
                main_path = os.path.join(process.ORIGINAL_DIR, 
main_path) 
            d['main_path'] = os.path.normpath(main_path) 
    return d 
When the program is running as a Windows service, but is not packaged 
into a single executable, main_path will become the path to the 
service executable (typically, pythonservice.exe). When this data 
makes it to the child process, the prepare() function will treat 
main_path as a path to a python module, and will try to import it. 
This causes it to fail. 
My quick-and-dirty solution was to check in get_preparation_data() if 
main_path ends with '.exe', and if it does, to not pass it at all. 
This solves the problem in my case, but perhaps there's a better way 
to fix this? Here is my version of get_preparation_data(): 
def get_preparation_data(name): 
    ''' 
    Return info about parent needed by child to unpickle process 
object 
    ''' 
    from .util import _logger, _log_to_stderr 
    d = dict( 
        name=name, 
        sys_path=sys.path, 
        sys_argv=sys.argv, 
        log_to_stderr=_log_to_stderr, 
        orig_dir=process.ORIGINAL_DIR, 
        authkey=process.current_process().authkey, 
        ) 
    if _logger is not None: 
        d['log_level'] = _logger.getEffectiveLevel() 
    if not WINEXE: 
        main_path = getattr(sys.modules['__main__'], '__file__', None) 
        if not main_path and sys.argv[0] not in ('', '-c'): 
            main_path = sys.argv[0] 
        if main_path is not None: 
            if not os.path.isabs(main_path) and \ 
                                      process.ORIGINAL_DIR is not 
None: 
                main_path = os.path.join(process.ORIGINAL_DIR, 
main_path) 
            if not main_path.endswith('.exe'): 
                d['main_path'] = os.path.normpath(main_path) 
    return d
History
Date User Action Args
2009-02-06 02:00:33orlenkosetrecipients: + orlenko, jnoller
2009-02-06 02:00:32orlenkosetmessageid: <1233885632.9.0.0484597105973.issue5162@psf.upfronthosting.co.za>
2009-02-06 02:00:31orlenkolinkissue5162 messages
2009-02-06 02:00:30orlenkocreate