【问题标题】:weird situation with file permissions on windowsWindows上文件权限的奇怪情况
【发布时间】:2012-02-08 10:09:04
【问题描述】:

所以我的项目结构如下。我有一个樱桃服务器和一个执行某些操作的后端服务器。现在我有一个“主”app.py 文件来处理启动这些进程。它们的开头如下:

    SERVER = subprocess.Popen([PYTHON_EXE_PATH, '-m', WEB_SERVER, 
                                    'tvb'], shell=False)

    BACKEND = subprocess.Popen([PYTHON_EXE_PATH, '-m', 'bin.rpserver'
                            , cfg.RPC_SERVER_IP, cfg.RPC_SERVER_PORT],
                            shell=False)

现在,在它们启动后,这些 pid 将存储在一个文件中,因此用户可以运行停止脚本并关闭它们。这些脚本也可以正常工作,基本上是:

def execute_stop():  
    if os.path.exists(PID_FILE):  
        pid_file = open(PID_FILE, 'r')
        has_processes = False
        for pid in pid_file.read().split('\n'):
            if len(pid.strip()):
                try:
                    if sys.platform == 'win32':
                        import ctypes
                        handle = ctypes.windll.kernel32.OpenProcess(1, False, 
                                                                int(pid))
                        ctypes.windll.kernel32.TerminateProcess(handle, -1)
                        ctypes.windll.kernel32.CloseHandle(handle)
                    else:
                        os.kill(int(pid), signal.SIGKILL) 
                except Exception, _:
                    has_processes = True
        if has_processes:
            sys.stdout.write("Some old PIDs were still registered; \
                          They could not be stopped.")                    
        pid_file.close()
    pid_file = open(PID_FILE, "w")
    pid_file.close()

现在这个 pid 文件,连同我的记录器文件和其他创建的数据文件都保存在 cfg.STORAGE 中,我还有一个简单的清理程序:

def execute_clean():
    """Remove TVB folder, TVB File DB, and log file."""
    try:
        if os.path.isdir(cfg.TVB_STORAGE):
            shutil.rmtree(cfg.TVB_STORAGE)
    except Exception, excep1:
        sys.stdout.write("Could not remove storage folder!")
        sys.stdout.write(str(excep1)) 

单独调用时也可以正常工作。但问题是:我的程序中有一个选项允许用户更改某些设置,在这种情况下,整个程序需要重新启动,并且应该重做这些步骤。为此我:

    cherrypy.engine.exit()
    self.logger.debug("Waiting for Cherrypy to terminate.")
    sleep(2)
    python_path = cfg().get_python_path()
    proc_params = [python_path, '-m', 'bin.app', 'start', 'web', 'backend']
    subprocess.Popen(proc_params, shell=False) 

所以这将再次基本上执行以下步骤:

    execute_stop()
    execute_clean()
    start both processes again

我无法理解的奇怪之处在于 execute_stop() 工作正常,正如您在末尾看到的那样,PID_FILE 以写入模式打开并关闭以清除内容,但随后立即在execute_clean() 失败后说PID_FILE 被另一个进程锁定。

现在我已经检查并重新检查,每次打开该文件时它都会关闭,我真的不知道该寻找什么了。这仅发生在 Windows 上,我尝试使用依赖项walker 来查看发生了什么,并且似乎当python 进程运行时,dependency walker 看到这些文件的4个引用和2个处理程序,考虑到它们,这很奇怪每次都关闭。我也觉得很奇怪,我可以在'w' 模式下打开文件,但我不能删除它们。

任何可能出错/寻找什么的想法将不胜感激。

编辑

我已经尝试按照建议使用 os.waitpid,但是在这样做时:

    os.waitpid(int(pid), 0) 

我收到了[Errno 10] No child processes。我也四处阅读,看到有人说在 Windows 上你应该将句柄而不是 pid 传递给 os.waitpid 所以我也用句柄尝试了它,但我得到了相同的结果。那么到那时这个过程应该不再存在了吧?

【问题讨论】:

    标签: python windows subprocess


    【解决方案1】:

    这只是在黑暗中拍摄...
    我的预感是 SERVER、BACKEND 进程中的一个或两个进程没有按预期终止并且有一个打开的 PID_FILE。检查他们每个人都使用mode='a' 打开 PID_FILE 并立即关闭它。除非我对 SERVER/BACKEND 处理 PID_FILE 的方式不满意,否则您也可以在致电 TerminateProcess 后尝试 os.waitpid(pid)。这应该阻塞,直到进程真正终止。

    【讨论】:

      猜你喜欢
      • 2016-10-03
      • 1970-01-01
      • 2020-08-08
      • 1970-01-01
      • 1970-01-01
      • 2016-04-28
      • 2010-09-17
      • 1970-01-01
      • 2013-04-14
      相关资源
      最近更新 更多