2012-02-08 13 views
0

私のプロジェクトは以下のように構成されています。私はcherrypyサーバーといくつかの操作を実行するバックエンドサーバーを持っています。今、これらのプロセスを開始するための「メイン」app.pyファイルがあります。Windows上でのファイルアクセス権のある奇妙な状況

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()が別のプロセスによってロックされていると言うことに失敗した後に即座に実行されます。

私はチェックして再チェックし、そのファイルが開かれるたびに閉鎖されており、もう何を探すべきか分からない。これはウィンドウ上でのみ発生し、何が起こっているのかを見るために依存関係ウォーカーを使用しようとしました。そして、Pythonプロセスが実行されているとき、依存関係ウォーカーはそれらのファイルに対して4つの参照と2つのハンドラを見ています。毎回閉じています。私はまた、'w'モードでファイルを開くことができて奇妙だと思っていますが、私はそれらを削除することはできません。

何が間違っているかもしれないか、何を探しているかは本当に高く評価されます。

EDIT

私が推薦しos.waitpidとして使用してみましたが、やってたときました:

os.waitpid(int(pid), 0) 

私は[Errno 10] No child processesを得ました。私はまた読んだことがありますが、誰かがウィンドウ上でハンドルをos.waitpidに渡す代わりにハンドルを渡すべきだと言ったので、ハンドルでも試しましたが、私は同じ結果を得ました。その時点でプロセスはもはや正しくないはずです。

答えて

0

これは暗闇の中のただのショットです...
私の勘違いは、SERVER、BACKENDプロセスのいずれかまたは両方が期待どおりに終了せず、開いているPID_FILEを持っていることです。それぞれがmode='a'でPID_FILEを開いていることを確認し、すぐに閉じます。私がSERVER/BACKENDがPID_FILEを処理する方法を根拠にしていない限り、TerminateProcessへの呼び出し後にos.waitpid(pid)を試すこともできます。これは、プロセスが本当に終了するまでブロックする必要があります。

関連する問題