python - 即使在主线程崩溃后,子线程也会继续运行
问题描述
我刚开始学习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 join
不要After join
打印。这让我相信主线程已经崩溃。
但是,正如您所看到的,它会自动再次开始打印,T-minus 7
这与我的想法相反,如果主线程崩溃,那么子线程也会崩溃。
为什么会这样?
解决方案
引发的异常只崩溃它所在的线程,而不是整个程序,因此进程保持活动状态,但是如果您将工作线程标记为守护线程,当您的所有非守护线程(例如主线程)退出时,它们将死亡。
因此,如果您想在主线程崩溃时退出程序,可以将守护进程标志设置为True
t = threading.Thread(target=c.run,args=(10,), daemon=True)
推荐阅读
- java - 使用参数从 java 运行 python
- c# - 如何在 SpinEdit 中显示浮点值?
- javascript - 如何在 Mongoose 查询中使用查询对象?
- amazon-web-services - 列的数据类型在粘合数据目录和 getCatalogSource 函数中有所不同
- python - 如何使用 Revit API 获取轴属性?
- mvvmcross - 使用此基本 ctor 从应用程序导航到基本视图模型的问题
- delphi - 在 Delphi 中对静态数组进行类型转换
- ios - 对于苹果的应用审查,我应该提供一个 testflight 的测试用户帐户吗?
- r - R - 每次从一列中的一个单元格在另一列中的每个单元格上运行
- csv - 如何在 Visual Studio Code 中删除嵌入的超链接