子线程可以杀死父线程吗?

时间:2019-07-04 08:21:26

标签: python multithreading

嗨,我有一个简单的问题:

我有一个产生多个线程(子线程)的父线程。如果子线程中的方法退出(1),父线程和其他子线程也将退出吗?

2 个答案:

答案 0 :(得分:1)

sys.exit()将仅关闭线程,os._exit()将终止整个程序:

使用sys.exit()

import sys, time
from threading import Thread


def testexit():
    print("in thread")
    time.sleep(5)
    sys.exit()
    print("after thread exit")  # will never print...


t = Thread(target=testexit)
t.start()
t.join()
print("in main, after thread exit")  # this will print...

输出:

in thread
in main, after thread exit

使用os._exit()

import sys, time
from threading import Thread
import os


def testexit():
    print("in thread")
    time.sleep(5)
    os._exit(1)
    print("after thread exit")  # will never print...


t = Thread(target=testexit)
t.start()
t.join()
print("in main, after thread exit")  # this will also not print...

输出:

in thread

答案 1 :(得分:1)

我写了一个小测试来找出我自己问题的完整答案:

import sys
import threading

import os

import time


class ThreadManager(object):
    default_threads = 8

    def __init__(self, thread_count=default_threads):
        self.threads = []
        self.thread_count = thread_count
        self.run_thread = None

    def add(self, thread):
        if not isinstance(thread, threading.Thread):
            sys.exit("Error: thread value must be of type: Thread")

        thread.ran = False
        self.threads.append(thread)

    def start(self):
        if not self.run_thread:
            print("starting run thread")
            self.run_thread = threading.Thread(target=self.run)
            self.run_thread.start()

        else:
            print("run thread already active")

    def run(self):
        unran_threads = [t for t in self.threads if not t.ran]
        while unran_threads:
            running_threads = [t for t in self.threads if t.isAlive()]
            while len(running_threads) < self.thread_count and unran_threads:
                thread = unran_threads.pop()
                print("starting thread: %s", thread.name)
                thread.start()
                thread.ran = True
                running_threads.append(thread)

            unran_threads = [t for t in self.threads if not t.ran]

        for thread in self.threads:
            thread.join()

        print("run thread completed")
        self.run_thread = None


def good_method():
    try:
        time.sleep(5)
        print(1/2)
    except ZeroDivisionError as zde:
        print(zde)
        exit(1)


def bad_method():
    try:
        print(1/0)
    except ZeroDivisionError as zde:
        print(zde)
        # os._exit(1)
        exit()


def main():
    tm = ThreadManager(4)
    tm.add(threading.Thread(target=bad_method))
    tm.add(threading.Thread(target=good_method))
    tm.add(threading.Thread(target=good_method))
    tm.add(threading.Thread(target=good_method))

    print('Start all threads')
    tm.run()
    print('Finish all threads')


if __name__ == '__main__':
    main()

看来,如果我执行一个简单的exit(),输出如下:

Start all threads
starting thread: %s Thread-4
starting thread: %s Thread-3
starting thread: %s Thread-2
starting thread: %s Thread-1
division by zero
0.5
0.5
0.5
run thread completed
Finish all threads

在其他地方,如果我使用osi._exit(1),则输出如下:

Start all threads
starting thread: %s Thread-4
starting thread: %s Thread-3
starting thread: %s Thread-2
starting thread: %s Thread-1
division by zero

结论:调用简单的exit()不会杀死父线程或同级子线程。调用osi._exit(1)将杀死所有人

感谢Adam.Er8让我知道如何进行自己的测试