子线程即使在主线程崩溃后仍保持运行

时间:2018-10-27 13:33:25

标签: python multithreading

我刚刚开始学习Python中的并发性,所以我的概念可能有点错误,在这种情况下,请纠正我。 以下所有情况都是在不知不觉中发生的。
这是我理解的简单线程示例-

import time
import threading

class CountDown:
    def __init__(self):
        self._running = True
    def stop(self):
        self._running = False

    def run(self, n):
        while self._running is True and n>0:
            print(f'T-minus {n}')
            n -= 1
            time.sleep(2)

c = CountDown()
t = threading.Thread(target=c.run,args=(10,))
t.start()
time.sleep(5)
c.stop()
print('Before join')
t.join()
print('After join')

哪个输出-

T-minus 10
T-minus 9
T-minus 8
Before join
After join

但是,如果我将stop的方法替换为terminate,则该方法尚未实现-

c = CountDown()
t = threading.Thread(target=c.run,args=(10,))
t.start()
time.sleep(5)
c.terminate()
c.stop()
print('Before join')
t.join()
print('After join')

哪个输出-

In [14]: runfile('/home/walker/Desktop/PYTHON/concurrency/2.py', wdir='/home/walker/Desktop/PYTHON/concurrency')
T-minus 10
T-minus 9
T-minus 8
Traceback (most recent call last):

  File "<ipython-input-14-3759e536ced7>", line 1, in <module>
    runfile('/home/walker/Desktop/PYTHON/concurrency/2.py', wdir='/home/walker/Desktop/PYTHON/concurrency')

  File "/home/walker/.local/lib/python3.6/site-packages/spyder_kernels/customize/spydercustomize.py", line 668, in runfile
    execfile(filename, namespace)

  File "/home/walker/.local/lib/python3.6/site-packages/spyder_kernels/customize/spydercustomize.py", line 108, in execfile
    exec(compile(f.read(), filename, 'exec'), namespace)

  File "/home/walker/Desktop/PYTHON/concurrency/2.py", line 28, in <module>
    c.terminate()

AttributeError: 'CountDown' object has no attribute 'terminate'


In [15]: T-minus 7
T-minus 6
T-minus 5
T-minus 4
T-minus 3
T-minus 2
T-minus 1

注意:
由于c.terminate(),很明显Before joinAfter join没有被打印。这让我相信主线程崩溃了。
但是,正如您所看到的,它自动从T-minus 7重新开始打印,这与我的想法相反,即如果主线程崩溃,那么子线程也会崩溃。
为什么会这样?

1 个答案:

答案 0 :(得分:1)

引发异常只会使它所在的线程崩溃,而不会使整个程序崩溃,因此该进程将保持活动状态,但是如果将工作线程标记为守护程序线程,则当所有非守护程序线程(例如主线程)具有退出。

因此,如果要在主线程崩溃时退出程序,可以将守护程序标志设置为reitLoopY

True