pythonプライマリスレッドとサブスレッドの終了順序
4074 ワード
自主スレッド終了がサブスレッドに与える影響を参照--YuanLiの一節:
プログラムの場合、サブプロセスが終了していないときにメインプロセスが終了した場合、Linuxカーネルはサブプロセスの親プロセスIDを1(つまりinitプロセス)に変更し、サブプロセスが終了するとinitプロセスによってサブプロセスが回収されます.
メインスレッドが終了した後のサブスレッドの状態は、その存在するプロセスに依存し、プロセスが終了しなければサブスレッドは正常に動作します.プロセスが終了すると、すべてのスレッドが終了するので、サブスレッドも終了します.
メインスレッドが終了し、プロセスはすべてのサブスレッドの実行が完了するまで待機します.
プロセスが開始されると、デフォルトでプライマリ・スレッドが生成されます.デフォルトでは、プライマリ・スレッドによって作成されるサブスレッドは、デーモン・スレッド(setDaemon(False))ではありません.したがって、プライマリ・スレッドが終了すると、サブスレッドは実行を継続し、プロセスはすべてのサブスレッドが完了するまで待機します.
すべてのスレッドが1つの端末出力を共有する(スレッドが属するプロセスの端末)
出力:
親スレッドが終了してもサブスレッドは実行され、プロセスが終了するとサブスレッドが終了します.
メインスレッドが終了すると、デーモンスレッドが完了するのを待たずにプロセスが終了します.
スレッドがデーモンスレッドに設定されている場合、このスレッドが属するプロセスはスレッドの実行が終了するのを待たず、プロセスはすぐに終了します.
出力:
thread 1はデーモンスレッドであり、thread 2はデーモンスレッドではないため、プロセスはthread 2の完了後に終了するのを待つのではなく、thread 1の完了を待つ
注:サブスレッドは、親スレッドのdaemonの値を継承します.つまり、デーモンスレッドが開いているサブスレッドはデーモンスレッドのままです.
メインスレッドはサブスレッドの完了後に終了するのを待つ
スレッドAでB.join()を使用すると、スレッドAが呼び出しjoin()でブロックされ、実行を続行するにはスレッドBの完了を待つ必要があることを示します.
出力:
メインスレッドはthread 2に実行する.join()はブロックされ、thread 2が終了するまで次の文が実行されません.
プログラムの場合、サブプロセスが終了していないときにメインプロセスが終了した場合、Linuxカーネルはサブプロセスの親プロセスIDを1(つまりinitプロセス)に変更し、サブプロセスが終了するとinitプロセスによってサブプロセスが回収されます.
メインスレッドが終了した後のサブスレッドの状態は、その存在するプロセスに依存し、プロセスが終了しなければサブスレッドは正常に動作します.プロセスが終了すると、すべてのスレッドが終了するので、サブスレッドも終了します.
メインスレッドが終了し、プロセスはすべてのサブスレッドの実行が完了するまで待機します.
プロセスが開始されると、デフォルトでプライマリ・スレッドが生成されます.デフォルトでは、プライマリ・スレッドによって作成されるサブスレッドは、デーモン・スレッド(setDaemon(False))ではありません.したがって、プライマリ・スレッドが終了すると、サブスレッドは実行を継続し、プロセスはすべてのサブスレッドが完了するまで待機します.
すべてのスレッドが1つの端末出力を共有する(スレッドが属するプロセスの端末)
import threading
import time
def child_thread1():
for i in range(100):
time.sleep(1)
print('child_thread1_running...')
def parent_thread():
print('parent_thread_running...')
thread1 = threading.Thread(target=child_thread1)
thread1.start()
print('parent_thread_exit...')
if __name__ == "__main__":
parent_thread()
出力:
parent_thread_running...
parent_thread_exit...
child_thread1_running...
child_thread1_running...
child_thread1_running...
child_thread1_running...
...
親スレッドが終了してもサブスレッドは実行され、プロセスが終了するとサブスレッドが終了します.
メインスレッドが終了すると、デーモンスレッドが完了するのを待たずにプロセスが終了します.
スレッドがデーモンスレッドに設定されている場合、このスレッドが属するプロセスはスレッドの実行が終了するのを待たず、プロセスはすぐに終了します.
import threading
import time
def child_thread1():
for i in range(100):
time.sleep(1)
print('child_thread1_running...')
def child_thread2():
for i in range(5):
time.sleep(1)
print('child_thread2_running...')
def parent_thread():
print('parent_thread_running...')
thread1 = threading.Thread(target=child_thread1)
thread2 = threading.Thread(target=child_thread2)
thread1.setDaemon(True)
thread1.start()
thread2.start()
print('parent_thread_exit...')
if __name__ == "__main__":
parent_thread()
出力:
parent_thread_running...
parent_thread_exit...
child_thread1_running...child_thread2_running...
child_thread1_running...child_thread2_running...
child_thread1_running...child_thread2_running...
child_thread1_running...child_thread2_running...
child_thread2_running...child_thread1_running...
Process finished with exit code 0
thread 1はデーモンスレッドであり、thread 2はデーモンスレッドではないため、プロセスはthread 2の完了後に終了するのを待つのではなく、thread 1の完了を待つ
注:サブスレッドは、親スレッドのdaemonの値を継承します.つまり、デーモンスレッドが開いているサブスレッドはデーモンスレッドのままです.
メインスレッドはサブスレッドの完了後に終了するのを待つ
スレッドAでB.join()を使用すると、スレッドAが呼び出しjoin()でブロックされ、実行を続行するにはスレッドBの完了を待つ必要があることを示します.
import threading
import time
def child_thread1():
for i in range(10):
time.sleep(1)
print('child_thread1_running...')
def child_thread2():
for i in range(5):
time.sleep(1)
print('child_thread2_running...')
def parent_thread():
print('parent_thread_running...')
thread1 = threading.Thread(target=child_thread1)
thread2 = threading.Thread(target=child_thread2)
thread1.setDaemon(True)
thread2.setDaemon(True)
thread1.start()
thread2.start()
thread2.join()
1/0
thread1.join()
print('parent_thread_exit...')
if __name__ == "__main__":
parent_thread()
出力:
parent_thread_running...
child_thread1_running...
child_thread2_running...
child_thread1_running...
child_thread2_running...
child_thread1_running...
child_thread2_running...
child_thread1_running...
child_thread2_running...
child_thread1_running...
child_thread2_running...
Traceback (most recent call last):
File "E:/test_thread.py", line 31, in
parent_thread()
File "E:/test_thread.py", line 25, in parent_thread
1/0
ZeroDivisionError: integer division or modulo by zero
メインスレッドはthread 2に実行する.join()はブロックされ、thread 2が終了するまで次の文が実行されません.
1/0
は、プライマリ・スレッドがエラーで終了し、thread 1がdaemon=Trueに設定されているため、プライマリ・スレッドが予期せぬ終了時にthread 1もすぐに終了します.thread1.join()はプライマリスレッドによって実行されません