ホームページ >バックエンド開発 >Python チュートリアル >Python デーモン デーモンの実装

Python デーモン デーモンの実装

高洛峰
高洛峰オリジナル
2017-02-10 09:10:091531ブラウズ

サーバープログラムを書く場合、ctrl+cで終了するかターミナルを閉じるとサーバープログラムが終了してしまうので、このプログラムをhttpdのようなデーモンプロセスにして常にバックエンドで動作しターミナルの影響を受けないようにすることを考えました。影響。

デーモンプロセスは、英語では httpd や mysqld のように daemon と呼ばれ、最後の文字 d は実際にはデーモンを意味します。

デーモンプロセスを作成する手順:

1. 子プロセスをフォークすると、親プロセスが終了します。このとき、子プロセスは init プロセスによって引き継がれます。
2. 子プロセスの作業ディレクトリを変更し、新しいプロセスの組み合わせと新しいセッションを作成し、umask を変更します。
3. 子プロセスが再度プロセスをフォークし、このプロセスを孫プロセスと呼び、子プロセスが終了します。
4. 孫プロセスの標準入力ストリーム、標準出力ストリーム、および標準エラーを /dev/null にリダイレクトします。上記の 4 つの手順を完了すると、最終的な孫プロセスがデーモン プロセスと呼ばれます。後でステップの理由を分析します。

#!/usr/bin/env python
#coding=utf8
def createDaemon():
  import os, sys, time
  #产生子进程,而后父进程退出
  try:
    pid = os.fork()
    if pid > 0:sys.exit(0)
  except OSError,error:
    print 'fork'
    sys.exit(1)
 
  #修改子进程工作目录
  os.chdir("/")
  #创建新的会话,子进程成为会话的首进程
  os.setsid()
  #修改工作目录的umask
  os.umask(0)
 
  #创建孙子进程,而后子进程退出
  try:
    pid = os.fork()
    if pid > 0:
      print "Daemon PID %d"%pid
      sys.exit(0)
  except OSError,error:
    print "fork"
    sys.exit(1)
  run()
 
 
def ping():
  import os
  os.system('ping www.baidu.com >/dev/nul')
 
def run():
  while True:
    import time,threading
    fd = open('/home/ping.log', 'a')
    fd.write("start time---------:%s\n"%time.ctime())
    fd.flush()
    t=threading.Thread(target=ping,args=())
    t.start()
    time.sleep(3)
    fd.write("end of time--------:%s\n"%time.ctime())
    fd.flush()
  fd.close()
 
if __name__=='__main__':
  createDaemon()

1. 子プロセスをフォークすると、親プロセスが終了します

通常、サーバープログラムを実行すると、接続が成功すると、シェル環境がロードされます。ターミナルとシェルは両方ともプロセスであり、シェルプロセスはターミナルプロセスの子プロセスです。このシェル環境で実行されるように開始されるプログラムはすべてシェルの子プロセスであることがわかります。当然、プログラム内で子プロセスをフォークした後、親プロセスは終了しますが、親プロセスが実行を完了しても、結果の子プロセスは init によって引き継がれます。プロセスを実行し、端末制御から脱却します。
2. 子プロセスの作業ディレクトリを変更する
子プロセスは、作成時に親プロセスの作業ディレクトリを継承します。実行されたプログラムが USB フラッシュ ドライブにある場合、USB フラッシュ ドライブはアンインストールできません。
3. 新しいセッションを作成します
setsid を使用すると、子プロセスは新しいセッションの最初のプロセスになり、子プロセスは新しいプロセス グループのリーダー プロセスになり、子プロセスはターミナルを制御しなくなります。
4. umask を変更します。
umask は権限をブロックするため、ファイルの読み取りおよび書き込み時の権限の問題を回避できます。
上記の手順の後、子プロセスが終了します。子プロセスが新しいプロセス グループのボスになると、ターミナルを開くために再適用できます。この問題を回避するには、孫プロセスの処理をフォークし、その標準入力ストリーム、標準出力ストリーム、および標準エラー ストリームをリダイレクトします。孫プロセスを/dev/nullに
しているため、デーモンプロセス自体がターミナルから切り離されているため、標準入力ストリーム、標準入力ストリーム、標準エラーストリームは意味が無いので、全て/dev/nullにリダイレクトされ、これは破棄を意味します。このプログラムを実行して効果を見てみましょう


上の図からわかるように、このスクリプトはバックグラウンドに置かれており、killall メソッドを使用することでのみ終了できます

次に見てみましょう。記録されたログを見てください

python daemon守护进程实现


その他の Python デーモン ガーディアン プロセスの実装に関連する記事については、PHP 中国語 Web サイトに注目してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。