[New-bugs-announce] [issue5162] multiprocessing cannot spawn child from a Windows service

Volodymyr Orlenko report at bugs.python.org
Fri Feb 6 03:00:32 CET 2009


New submission from Volodymyr Orlenko <orlenko at gmail.com>:

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

----------
components: Library (Lib)
files: forking-patch
messages: 81247
nosy: jnoller, orlenko
severity: normal
status: open
title: multiprocessing cannot spawn child from a Windows service
type: behavior
versions: Python 2.6
Added file: http://bugs.python.org/file12949/forking-patch

_______________________________________
Python tracker <report at bugs.python.org>
<http://bugs.python.org/issue5162>
_______________________________________


More information about the New-bugs-announce mailing list