pythonバックグラウンドデーモンの作成

10660 ワード

pythonサービスプログラムを作成し、コマンドラインの下で起動し、コマンドラインセッションは端末によって制御され、pythonサービスは端末プログラムのサブプロセスになります.そのため、端末を閉じると、このコマンドラインプログラムも閉じます.pythonサービスを端末の影響を受けずにシステムに常駐させるには、それをデーモンプロセスにする必要があります.デーモンプロセスはDaemonプログラムであり、システムのバックグラウンドで実行されるプログラムであり、制御端末とは独立していくつかのサイクルタスクまたはトリガイベントを実行し、一般的にhttpd、syslogd、systemd、dockerdなどの「d」アルファベットの末尾と命名される.
コード実装
pythonは、デーモンプロセスを簡潔に実装できます.次に、コードと対応する注釈を示します.
# coding=utf8
import os
import sys
import atexit


def daemonize(pid_file=None):
    """
          
    :param pid_file:     id   
    :return:
    """
    #     fork       
    pid = os.fork()
    #     pid   0,     0
    if pid:
        #      ,sys.exit()   os._exit()              
        sys.exit(0)

    #                ,         ,            
    os.chdir('/')
    #            umask(      ),   0(    ),          
    os.umask(0)
    #                  
    os.setsid()

    #    ,    2 fork,          ,          
    _pid = os.fork()
    if _pid:
        #      
        sys.exit(0)

    #   ,            ,          、  、      (         ,           print      )

    #       ,       
    sys.stdout.flush()
    sys.stderr.flush()

    # dup2                ,    /dev/nul,         
    with open('/dev/null') as read_null, open('/dev/null', 'w') as write_null:
        os.dup2(read_null.fileno(), sys.stdin.fileno())
        os.dup2(write_null.fileno(), sys.stdout.fileno())
        os.dup2(write_null.fileno(), sys.stderr.fileno())

    #   pid  
    if pid_file:
        with open(pid_file, 'w+') as f:
            f.write(str(os.getpid()))
        #       ,         pid  
        atexit.register(os.remove, pid_file)

デーモンプロセスの作成手順を要約します.
forkはサブプロセスを出し、親プロセスを終了する.
サブプロセス変更作業ディレクトリ(chdir)、ファイル権限マスク(umask)、プロセスグループ、セッショングループ(setsid)サブプロセスfork孫プロセス、サブプロセスを終了
孫プロセスはバッファをリフレッシュし、標準入出力/エラー(一般的に/dev/null、すなわち破棄)にリダイレクトする.
(オプション)pid書き込みファイルいくつかの要点を理解する
なぜforkは2回
初めてのforkは、端末制御の魔の爪から離れるためだ.親プロセスが終了したのは、端末がキーボードを叩いたり、閉じたりしたときに信号を送ったからです.forkから出たサブプロセスは,親プロセスが自殺した後に孤児プロセスとなり,オペレーティングシステムのinitプロセスに引き継がれるため,端末制御から離脱する.だから実は、2回目のforkは必須ではありません(多くのオープンソースプロジェクトのコードにはforkが2回もありません).ただし、慎重に考慮して、プロセスが再び制御端末を開くことを防止します.サブプロセスは現在セッションリーダー(セッション期間の最初のプロセス)であるため、制御端末を開く能力があり、もう一度forkすると、孫プロセスは制御端末を開くことができなくなる.
ファイル記述子
Linuxは「すべてファイル」であり、ファイル記述子はカーネルが開いたファイルのインデックスであり、通常は非負の整数である.プロセスは、ファイル記述子によってIO操作を実行します.デフォルトでは、0は標準入力、1は標準出力、2は標準エラーです.
umask権限マスク
Linuxでは、どのファイルにもリード(read)、ライト(write)、実行(execute)の3つの使用権限があることを知っています.このうち,読み取りの権限は数字4で表し,書き込みの権限は2,実行の権限は1である.コマンドls-lは、ファイル権限を表示することができ、r/w/xは、それぞれ、読み取り/書き込み/実行権限を有することを示す.どのファイルにも、ユーザー(User)、ユーザーグループ(Group)、その他のグループ(Others)の3つのアイデンティティ権限があります.ファイル権限は、一般的に3つの数字で表されます.たとえば、754です.
7は、User権限、すなわちファイル所有者権限である.
5は、Group権限であり、所有者が所属するユーザグループのメンバが有する権限である.
4は、Others権限、すなわち他のグループのユーザの権限であるumaskは、デフォルトの権限を制御し、新しいファイルやフォルダに全権があることを防止するためです.システムの一般的なデフォルトは022です(コマンドumaskを使用して表示されます).デフォルトでファイルを作成する権限は644で、フォルダは755です.ファイル権限とumaskの加算結果は666(笑)、フォルダ権限とumaskの加算結果は777という法則が見られるはずです.
プロセスグループ
各プロセスは1つのプロセスグループ(PG,Process Group)に属し、プロセスグループは複数のプロセスを含むことができる.プロセスグループにはプロセスグループ長(リーダー)があり、プロセスグループ長のID(PID,Process ID)はプロセスグループ全体のID(PGID,Process Group ID)となる.
セッショングループ
端末にログインすると、1つのセッションが作成され、複数のプロセスグループが1つのセッションに含めることができます.セッションを作成するプロセスは、セッショングループ長です.すでにセッショングループ長のプロセスであり、setsid()メソッドを呼び出してセッションを作成することはできません.したがって、上記のコードでは、サブプロセスはsetsid()を呼び出すことができ、親プロセスは、それ自体がセッショングループ長であるため、呼び出すことができません.また、sh(Bourne Shell)はセッションメカニズムをサポートしない.セッションメカニズムにはshellサポート作業制御(Job Control)が必要であるからである.
デーモンプロセスとバックグラウンドプロセス
&シンボルで、コマンドをバックグラウンドに置いて実行できます.デーモンプロセスとは異なります.
守護プロセスは端末とは関係なく、initプロセスによって養子縁組された孤児プロセスである.バックグラウンドプロセスの親プロセスは端末であり、端末でを印刷することができる.
ガードプロセスは端末を閉じるときも堅調です.nohup を追加しない限り、バックグラウンドプロセスはユーザーの終了に伴って停止します.
デーモン・プロセスは、セッション、プロセス・グループ、作業ディレクトリ、およびファイル・ディスクリプタを変更し、バックグラウンド・プロセスは親プロセス(shell)のを直接継承します.
言い換えれば、プロセスを守ることは黙々と奮闘して戦う有為な青年であり、バックグラウンドプロセスは黙々と父の資産を受け継ぐ富の2世代である.
テキストリンク: