posts - 101,  comments - 57,  trackbacks - 0

source: http://bugs.python.org/issue5162

classificationTitle: multiprocessing cannot spawn child from a Windows service  
Type: behavior Stage: test needed
Components: Library (Lib) Versions: Python 2.6
processStatus: open Resolution: 
Dependencies:   Superseder: 
Assigned To: jnoller  Nosy List:  jnoller, orlenko (2) 
Priority:  normal Keywords patch
 
Created on 2009-02-06 02:00 by orlenko, last changed 2009-03-29 15:44 by jnoller.

Files
File name Uploaded Description Edit Remove
forking-patch  orlenko, 2009-02-06 02:00  Patch of the forking module  
Messages (1)
msg81247 - (view) Author: Volodymyr Orlenko (orlenko) Date: 2009-02-06 02:00 
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

posted on 2010-01-27 17:51 margin 阅读(229) 评论(0)  编辑 收藏 引用 所属分类: Pathon

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


<2024年4月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

常用链接

留言簿

随笔档案

文章分类

文章档案

收藏夹

常去的坛子

  • CVC电脑病毒论坛
  • 很多人说我是AV,我告诉他们:别瞧不起人,我们也能创造价值
  • 安全焦点
  • 黑客聚集的地方,一般是好酒最多的地方...
  • 看雪论坛
  • 国内最强的加密解密论坛,成醉其中经常夜不归宿
  • 驱动开发论坛
  • 厌倦了啤的朋友们,来我们来整点白的...痛痛快快的BSOD也好过隔鞋瘙痒!

我的朋友

  • Sen的blog
  • IDE方面资深的受害者...经常为一个变量的定义找不着北的痛苦程序员(深表同情)
  • 老罗的blog
  • 良师益友,千年水牛,引擎猛男,分析怪兽,墨镜酷哥,台球高手....

搜索

  •  

最新评论