12

私のPythonスクリプトは、無期限に実行されるプロセスを生成できますか?

私はPythonにもスポーンするデーモンにもあまり詳しくないので、次のように思いつきます。

si = subprocess.STARTUPINFO()
si.dwFlags = subprocess.CREATE_NEW_PROCESS_GROUP | subprocess.CREATE_NEW_CONSOLE
subprocess.Popen(executable, close_fds = True, startupinfo = si)

プロセスは引き続きpython.exeを超えて実行されますが、cmdウィンドウを閉じるとすぐに閉じられます。

4

3 に答える 3

20

答えを使用して、Janne Karilaは、これが、親が死んだときに死なないプロセスを実行する方法であり、win32processモジュールを使用する必要がないことを指摘しました。

DETACHED_PROCESS = 8
subprocess.Popen(executable, creationflags=DETACHED_PROCESS, close_fds=True)

DETACHED_PROCESS基になるCreateProcess関数に渡されるプロセス作成フラグです。

于 2012-10-12T07:37:39.577 に答える
18

この質問は3年前に行われたもので、回答の基本的な詳細は変更されていませんが、「Windows Pythonデーモン」検索での普及を考えると、将来のGoogleの到着のためにいくつかの議論を追加することが役立つかもしれないと思いました。

質問には実際には2つの部分があります。

  1. Pythonスクリプトは、無期限に実行される独立したプロセスを生成できますか?
  2. PythonスクリプトはWindowsシステムでUnixデーモンのように機能できますか?

最初の答えは明白です。すでに指摘したように; キーワードとsubprocess.Popen一緒に使用するだけで十分です。creationflags=subprocess.CREATE_NEW_PROCESS_GROUP

import subprocess

independent_process = subprocess.Popen(
    'python /path/to/file.py',
    creationflags=subprocess.CREATE_NEW_PROCESS_GROUP
)

少なくとも私の経験でCREATE_NEW_CONSOLEは、ここでは必要ないことに注意してください。

そうは言っても、この戦略の動作は、Unixデーモンに期待するものとはまったく同じではありません。正常に動作するUnixデーモンを構成するものについては、他の場所で詳しく説明していますが、要約すると次のようになります。

  1. 開いているファイル記述子を閉じます(通常はすべてですが、一部のアプリケーションでは一部の記述子を閉じないように保護する必要があります)
  2. 「DirectoryBusy」エラーを防ぐために、プロセスの作業ディレクトリを適切な場所に変更します
  3. ファイルアクセス作成マスクを変更する(os.umaskPythonの世界で)
  4. アプリケーションをバックグラウンドに移動し、開始プロセスからアプリケーションを切り離します
  5. STDIN、、STDOUTSTDERR別のストリーム(多くの場合)にリダイレクトすることを含め、端末から完全に離婚しDEVNULL、制御端末の再取得を防ぎます
  6. 特に信号を処理しますSIGTERM

状況の現実は、オペレーティングシステムとしてのWindowsがデーモンの概念を実際にサポートしていないということです。ターミナルから(またはエクスプローラーからの起動など、他のインタラクティブなコンテキストで)起動するアプリケーションは引き続き実行されます。制御アプリケーション(この例ではPython)にウィンドウのないGUIが含まれていない限り、ウィンドウが表示されます。さらに、Windowsのシグナル処理はひどく不十分であり、独立したPythonプロセスにシグナルを送信しようとすると(ターミナルの閉鎖に耐えられないサブプロセスとは対照的に)、ほとんどの場合、クリーンアップなしでそのPythonプロセスがすぐに終了します(finally:、いいえatexit、いいえ__del__など)。

アプリケーションをWindowsサービスにロールインすることも、多くの場合実行可能な代替手段ですが、完全には適合しません。同じことが使用にも当てはまりますpythonw.exe(最近のすべてのWindows Pythonバイナリに同梱されているウィンドウレスバージョンのPython )。特に、信号処理の状況を改善することができず、端末からアプリケーションを簡単に起動して起動時に対話することはできません(たとえば、動的な起動引数をスクリプトに配信するために、たとえばパスワード、ファイルなど)パスなど)、「デーモン化」。さらに、Windowsサービスにはインストールが必要です。これは、実行時に「デーモン」を最初に呼び出したときにすばやく実行できますが、ユーザーのシステム(レジストリなど)を変更します。 Unixの世界。

pythonw.exeそれを踏まえると、を使用してサブプロセスを起動することsubprocess.CREATE_NEW_PROCESS_GROUPは、従来のUnixデーモンをエミュレートするPythonプロセスに相当するWindowsにおそらく最も近いものであると私は主張します。ただし、それでも信号処理とスタートアップ通信の追加の課題が残ります(コードをプラットフォームに依存させることは言うまでもなく、これは常に苛立たしいことです)。

とはいえ、将来この問題が発生する人のために、適切なUnixデーモン化上記の戦略の両方をラップするdaemonikerというライブラリを作成しました。また、(UnixシステムとWindowsシステムの両方で)信号処理を実装し、pickleを使用してオブジェクトを「デーモン」プロセスに渡すことができます。何よりも、クロスプラットフォームのAPIがあります

from daemoniker import Daemonizer

with Daemonizer() as (is_setup, daemonizer):
    if is_setup:
        # This code is run before daemonization.
        do_things_here()

    # We need to explicitly pass resources to the daemon; other variables
    # may not be correct
    is_parent, my_arg1, my_arg2 = daemonizer(
        path_to_pid_file,
        my_arg1,
        my_arg2
    )

    if is_parent:
        # Run code in the parent after daemonization
        parent_only_code()

# We are now daemonized, and the parent just exited.
code_continues_here()
于 2016-09-27T02:24:20.737 に答える
7

その目的のために、Pythonプロセスをデーモン化するか、Windows環境を使用しているときに、これをWindowsサービスとして実行することができます。

あなたは私がウェブリンクだけを投稿するのが嫌いなことを知っています:

ただし、要件に応じた詳細については、次のとおりです。

Windowsサービスを実装する簡単な方法すべてのコメントを読んで、疑問を解決します

あなたが本当にもっと学びたいのなら

最初にこれを読んでください

デーモンプロセスまたはcreateing-a-daemon-the-python-wayとは何ですか

更新: サブプロセスは、この種のことを達成するための正しい方法ではありません

于 2012-10-11T16:44:34.537 に答える