如果需要,如何正确、干净地终止python程序<代码>系统。exit()不能可靠地执行此功能,因为它只是终止调用它的线程,exit()
和quit()
不应使用,除非在终端窗口中,raise SystemExit
与sys存在相同的问题。exit()
是一种坏习惯,并且os_exit()
会立即杀死所有东西,并且不会清理,这可能会导致残留物问题。
有没有办法总是杀死程序和所有线程,不管它是从哪里调用的,同时仍然清理?
当你的应用程序运行时,可能会发生不好的事情,我们希望从中恢复。一个例子是停电。
没有计算技术可以安排指令在断电的设备上执行。因此,我们可能需要在重新启动时重置一些状态。您的应用程序已经有此要求;我只是说得很清楚。
正如您在仔细考虑几种标准技术时发现的那样,在可能发生的各种不好的事情发生之后,很难可靠地获得控制权。你并没有具体的项目需要清理,你设想,但我们可以考虑这些情况:
与其直接调用应用程序,不如安排它由Nanny进程运行,该进程将应用程序作为子进程分叉。在某个时候,应用程序将退出,保姆将重新获得控制权,所有瞬态项目已被操作系统整理,然后保姆可以在应用程序重启之前对永久项目进行任何必要的清理。这与Nanny在初始启动时需要进行的清理相同,例如在电源故障事件之后。在父进程下运行应用的优点是,父进程可以在简单的应用故障(如SEGV)后立即执行清理。
清理永久项目可能涉及时间戳资源的超时。如果您的系统能够在短暂停电后的2秒内重新启动,您可能会发现有必要故意保持Down(睡眠)足够长的时间,以确保远程主机在宣布向Up过渡之前可靠地检测到您向Down的过渡。虚拟同步和Paxos等技术可以帮助您实现快速融合。
有时,在运行清理代码之前,应用程序会意外死亡。采取安全带和吊杆的方法:将基本清理代码放在(更简单、更可靠)父进程中。
有没有办法总是杀死程序和所有线程,不管它是从哪里调用的,同时仍然清理?
否-“无论从何处调用”和“清理”不要混合使用。
既可靠又安全地杀死线程是没有意义的。杀死一个线程(或进程)意味着中断它正在做的事情——包括清理。不中断任何清理意味着,嗯,实际上没有杀死线程。你不能同时拥有两者。
如果您想杀死所有线程,那么os_exit()
正是您想要的。如果您想清理线程,没有通用特性可以满足这一要求。
关闭线程的唯一可靠方法是实现您自己的安全中断。在某种程度上,这必须根据您的用例进行定制——毕竟,您是唯一知道何时可以安全关闭的人。
底层CPython API允许您在另一个线程中引发异常。参见例如这个答案。
这不是便携式的,也不安全。您可以在任意点终止该线程。如果您的代码期望出现异常,或者您的资源在发生异常后(通过\uuuu del\uuuu
)进行清理,则可以限制伤害,但不能排除伤害。不过,这与大多数人认为的“干净利落”非常接近。
线程与线程一起运行。如果没有其他线程保留,守护进程将突然终止。通常,这是您想要的一半:如果所有正确的线程都退出,则优雅地终止。
现在,关键是守护进程
线程不能阻止关闭。这也意味着它不会阻止运行atexout
!因此,守护进程可以使用atexout
自动关闭自己并在终止时进行清理。
import threading
import atexit
import time
class CleanThread(threading.Thread):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.daemon = True
# use a signal to inform running code about shutdown
self.shutdown = threading.Event()
def atexit_abort(self):
# signal to the thread to shutdown with the interpreter
self.shutdown.set()
# Thread.join in atexit causes interpreter shutdown
# to be delayed until cleanup is done
self.join() # or just release resources and exit
def run(self):
atexit.register(self.atexit_abort)
while not self.shutdown.wait(0.1):
print('who wants to live forever?')
print('not me!')
atexit.unregister(self.atexit_abort)
thread = CleanThread()
thread.start()
time.sleep(0.3)
# program exits here
请注意,这仍然需要您的代码监听清理信号!根据Thread的功能,还有其他机制可以实现这一点。例如,concurrent.future
模块在关机时清空所有工作线程的任务队列。
我有一个非常基本的登录servlet 当我从登录名调用servlet时。html: 如果输入了正确的用户名和密码,浏览器将正确呈现login\u success。jsp。但是,当我没有输入正确的用户名和密码时,浏览器会将未渲染的html显示为纯文本: 如何让LoginServlet将消息放在正确的位置(在body标签之后)?谢谢
问题内容: 无论当前屏幕的方向(横向或纵向)如何,我都希望获得当前的磁方向。 我找到了这个例子,但它不是方向独立的,对不对?而这也帮不了我。我确实也阅读了http://android- developers.blogspot.de/2010/09/one-screen-turn-deserves- another.html 。 这是我当前使用的方法,不想使用(过短的)废弃方法: 但是最后一部分肯定
问题内容: 我一直在使用该功能来暂停脚本: 有正式的方法吗? 问题答案: 对我来说似乎很好(或在Python 2.X中)。或者,如果您想暂停一定的秒数,则可以使用。
问题内容: 一个众所周知的事实是,不要停止使用Thread.stop()运行进程。 通常,手册和教程建议改用Thread.interrupt()或一些布尔变量,并从代码内部检查该中断或变量。 但是,如果我有一个库方法有时需要花费很长时间才能执行,并且我想让用户能够停止该过程?库没有给我提供执行此操作的机制(不检查线程中断状态,也没有“ stop!”变量)? 而且,更糟糕的是,要么没有库的源代码,要
假设我有一个python包的标准python目录结构,就像这里一样,并考虑我需要向包中添加一个函数。更具体地说,我想通过运行一个测试代码,用试错法来做这件事。正确的工作流程是什么? 我目前做以下工作: 做,只要我在包中进行更改 打开一个 Python 解释器, 运行测试代码。 但显然,此流程需要花费大量时间来通过测试代码检查修改。我觉得我做错了什么,更好的方法存在。
我有一个正在运行的Spark应用程序,它占据了所有核心,而我的其他应用程序将不会被分配任何资源。 我做了一些快速的研究,人们建议使用YARN kill或 /bin/spark-class来杀死命令。然而,我使用的是CDH版本, /bin/spark-class根本不存在,YARN kill应用程序也不起作用。 有人能和我一起吗?