ソリューション:Pythonのマルチプロセッシング、トラブルの再起動のプロセスを終了し、予防ゾンビ
ゾンビプロセスは以下のとおりです。リック・サンダースに
おかげで、プロセスを終了した後にこの機能を追加すると、問題を解決しますプロセスが終了したときに作成され、終了コードを要求することによってそれらが収穫されている場合を除きます。親はそれが終了コードを要求できるという目的のために残りますが、スクリプトが本当に終了しないので、プロセスはexecv(file, args)
に置き換えられます。親は終了コードを要求せず、ゾンビプロセスが保持されます。これは私のOSXシステムとDebianシステムの両方で動作します。
私は非常に大きなスクリプトを作成しており、最近電子メールを受信するためにマルチプロセッシングとIMAPを実装しています。私はこれを実装する前に、私はそれがない一言で言えば、私は編集後のスクリプトを更新するには、コマンドラインで入力することができ、再起動のコマンドを実装していたこの:
if ipt = ':rs':
execv(__file__)
それは暫定でがらくたの束を出力し、しかし。
私もそうのようなwhileループでは、GoogleのIMAPサーバーに耳を傾け、別のオブジェクトで実行中のプロセス、持っている:ので、私は私が再起動したときに、私はゾンビを作成していた気づいた、見て上部から
While True:
mail = imaplib.IMAP4_SSL('imap.gmail.com')
mail.login('[email protected]', 'mypassword')
mail.list()
mail.select("inbox")
result, data = mail.uid('search', None, 'All')
latest_email_uid = data[0].split()[-1] #grabs the most recent email by
#unique id number
if int(latest_email_uid) != int(last_email_uid): # set earlier from sql
# database
# do stuff with the mail
else:
continue
を
def process_terminator(self):
self.imap_listener.terminate()
そして、私は、再起動からそれを呼ばれる:私は、終了関数を作成し
if ipt == ':rs':
self.process_object.terminate()
execv(__file__)
しかし、ゾンビプロセスは依然として存続しています。だから、数時間の作業の後、私は関数を呼び出した後にtime.sleepの期間を追加し、ローカル変数をプロセスのexitcodeに設定するか、プロセスのexitcodeを出力することによって、プロセスが終了することを認識しました。 0.1秒:
if ipt == ':rs':
self.process_object.terminate()
time.sleep(.1)
print(self.process_object.imap_listener.exitcode)
execv(__file__)
このOSXにそうではない、しかし、単に処理を実行.terminate()関数は、処理を終了する、しかし私のDebianマシン上で、I(n)は、睡眠を持たなければならない期間プロセスの終了コードを何らかの形でまたはファッションで参照して、それがzombyingするのを防ぐ必要があります。
私はまた、私のスクリプト全体をハングアップしますが、.joinを使ってみました。私は(例えば)self.terminated = 1のときにプロセスがwhileループを壊すように変数を作成しようとしましたが、それでも結合できません。
exec( 'quit')を実行しているときにこの問題はありません。処理を終了すると、.join()は機能しません。
私の一部の誤解を指摘できますか?私は自分自身の研究を試みたが、十分な解決策を見つけられていないし、プロセスがうまく終了しないようにプロセスを明示的に終了すべきではないことを認識しているが、
申し訳ありませんが、私が提供するコードはもうありません。必要に応じてより多くの情報を提供するために最善を尽くします。これらはスクリプト(1000+行)の関連するコードのスニペットです。
ああ、プロセステーブルから削除する前に終了コードを読まなければならない理由を説明しています。私は自分のコードを調整し、それがこの問題を解決するかどうか確認します。ありがとうございました! –
恐ろしい!これは働いていた: 'デフprocess_terminator(自己): self.imap_listener.terminate() waitpidの(self.imap_listener.pidを、0)' 少なくともOSX上で、今、私のDebianシステム上でそれをしようとします... –