2016-11-03 15 views
2

メインスレッドが終了したときにデーモンスレッドはどうなりますか?彼らはどのように閉鎖されていますか?クリーンアップコードが確実に実行される方法はありますか?しばらく1メインスレッドが死亡した場合転がっ私は任意の一時ファイル(またはゾンビプロセス)を残していないことを確認したいデーモンスレッドはどのようにPythonで殺されますか(2.7)

import os 
import subprocess 
import threading 
import glob 
import datetime 

def do_big_job(result='result.txt'): 
    tmpfile = result+'.tmp' 
    err = subprocess.call(['my_time_consuming_script', '-o', tmpfile]) 
    if err == 0: 
     os.rename(tmpfile, result) 
    else: 
     os.remove(tmpfile) # process failed, clean up temp file 



def main(): 
    not_done = True 
    update = 0 
    while not_done: 

     # we can see if new data are available, 
     # and start a process to get/prep it 
     if new_data_available(): 
      args = ('result{0:05}.txt'.format(update),) 
      th = threading.Thread(target=do_big_job, args=args) 
      update = update + 1 
      th.daemon = True 
      th.start() 

     # but we don't need/want to wait for that process 
     # to complete before continuing to iterate 

     currently_available = glob.glob('result*.txt') 
     # <snip> 
     # rest of loop just uses what is available, 
     # we don't want/need to block for updated data 
     # to meet other responsiveness requirements 

:ここ

は、私が持っているような状況のスケッチですdo_big_jobスレッドの数(またはそれ以上)がまだ実行中ですが、メイン終了時に完了するのを待つことができないため、daemon=Falseも設定できません。

答えて

1

メインスレッドが終了すると、すべてのデーモンスレッドも終了します。したがって、main()がすべてのデーモンスレッドを終了しても終了します。

しかし、I/O操作のための公式のPythonスレッディングdocsによれば、あなたの質問の第2部に来て、これは正常に行われないかもしれません。

シャットダウン時にデーモンスレッドが突然停止します。それらのリソース(オープンファイル、データベーストランザクションなど)は適切に解放されないことがあります。スレッドを正常に停止させたい場合は、それらを非デーモンにし、イベントなどの適切なシグナリングメカニズムを使用します。

ゾンビスレッドがあるかどうかをチェックするには、isAlive()関数を呼び出します。 メインスレッドが終了した後にクリーンアップコードが実行されるようにする方法については、私はそれがあなたが意味するものに依存すると思うを死ぬ。

スクリプトの正常終了(KeyboardInterrupt例外、sys.exit()が呼び出されたなど)の場合は、処理の終了時に実行される関数を登録するatexitモジュールを実際に見てみる価値があります。

main()がシグナルによって殺されるか、Pythonの致命的な内部エラーが発生するか、os._exit()が呼び出された場合、atexitモジュールは機能しません。その場合、考えられる解決策は、main()を常に監視し、適切なときにクリーンアップコードを実行する別のウォッチドッグプロセスを作成することです。

関連する問題