web-dev-qa-db-ja.com

Python子サブプロセスを生成し、切り離して終了する

これがシステムプロセスを実行して親から切り離す正しい方法であるかどうか疑問に思っています。ただし、ゾンビを作成したり子プロセスを強制終了したりせずに親を終了できます。私は現在サブプロセスモジュールを使用しており、これを行っています...

os.setsid() 
os.umask(0) 
p = subprocess.Popen(['nc', '-l', '8888'],
                     cwd=self.home,
                     stdout=subprocess.PIPE, 
                     stderr=subprocess.STDOUT)

os.setsid()はプロセスグループを変更します。これにより、親の終了時にプロセスが同じプロセスグループに属しなくなったため、プロセスを実行し続けることができると思います。

これは正しいですか、またこれはこれを実行する信頼できる方法ですか?

基本的に、ソケットを介して通信し、リモートでプロセスを開始できるリモートコントロールユーティリティがありますが、リモートコントロールが停止しても、開始したプロセスが影響を受けずに実行し続けることを確認する必要があります。

私はダブルフォークについて読んでいて、これが必要であるかどうか、および/またはサブプロセスであるかどうかわかりませんでした。

ありがとう。

イリヤ

31
Ilya Sterin

UNIXでのpopenforkを使用して完了 です。それはあなたが安全であることを意味します:

  1. 親プロセスでPopenを実行します
  2. すぐに親プロセスを終了する

親プロセスが終了すると、子プロセスはinitプロセス(OSXではlaunchd)に継承され、引き続きバックグラウンドで実行されます。

pythonプログラムの最初の2行は必要ありません。これは完全に機能します。

_import os, time
import subprocess
p = subprocess.Popen(['nc', '-l', '8888'],
                     cwd="/",
                     stdout=subprocess.PIPE,
                     stderr=subprocess.STDOUT)
_

私はダブルフォークについて読んでいて、これが必要かどうかわかりませんでした

これは、親プロセスが実行され続け、子供が親と一緒に死ぬのを防ぐ必要がある場合に必要です。 この答え は、これをどのように実行できるかを示しています。

ダブルフォークのしくみ:

  1. os.fork()を介して子を作成します
  2. この子でPopen()を呼び出し、長時間実行プロセスを起動します
  3. exit child:Popenプロセスはinitに継承され、バックグラウンドで実行されます

なぜ親はすぐに出なければならないのですか?すぐに終了しない場合はどうなりますか?

親を実行したままにし、ユーザーがプロセスを停止した場合。 _ctrl-C_(SIGINT)または_ctrl-\_(SIGQUIT)を使用すると、親プロセスとPopenプロセスの両方が強制終了されます。

フォークしてから1秒後に終了するとどうなりますか?

次に、この1秒間にPopenプロセスはctrl-cなどに対して脆弱です。100%にする必要がある場合は、ダブルフォークを使用してください。

11
hansaplast