- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我见过很多与此相关的问题...但我的代码可以在 python 2.6.2 上运行,无法在 python 2.6.5 上运行。我是否认为整个 atexit“当程序被信号杀死时不会调用通过此模块注册的函数”这件事在这里不算数,因为我正在捕获信号然后干净地退出,我认为这是错误的吗?这里发生了什么?执行此操作的正确方法是什么?
import atexit, sys, signal, time, threading
terminate = False
threads = []
def test_loop():
while True:
if terminate:
print('stopping thread')
break
else:
print('looping')
time.sleep(1)
@atexit.register
def shutdown():
global terminate
print('shutdown detected')
terminate = True
for thread in threads:
thread.join()
def close_handler(signum, frame):
print('caught signal')
sys.exit(0)
def run():
global threads
thread = threading.Thread(target=test_loop)
thread.start()
threads.append(thread)
while True:
time.sleep(2)
print('main')
signal.signal(signal.SIGINT, close_handler)
if __name__ == "__main__":
run()
python 2.6.2:
$ python halp.py
looping
looping
looping
main
looping
main
looping
looping
looping
main
looping
^Ccaught signal
shutdown detected
stopping thread
python 2.6.5:
$ python halp.py
looping
looping
looping
main
looping
looping
main
looping
looping
main
^Ccaught signal
looping
looping
looping
looping
...
looping
looping
Killed <- kill -9 process at this point
2.6.5 上的主线程似乎从不执行 atexit 函数。
最佳答案
这里的根本区别实际上与信号和 atexit 都无关,而是 sys.exit
行为的变化。
在 2.6.5 左右之前,sys.exit
(更准确地说,SystemExit 在顶层被捕获)会导致解释器退出;如果线程仍在运行,它们将被终止,就像 POSIX 线程一样。
在 2.6.5 左右,行为发生了变化:sys.exit
的效果现在与从程序的主函数返回基本相同。当您执行那个时——在两个版本中——解释器在退出之前等待所有线程被加入。
相关的变化是 Py_Finalize
现在会在顶部附近调用 wait_for_thread_shutdown()
,而以前不会。
此行为更改似乎不正确,主要是因为它不再像记录的那样运行,即:“退出 Python”。实际效果不再是退出Python,而是简单的退出线程。 (作为旁注,sys.exit
在从另一个线程调用时从未退出 Python,但是与记录的行为的模糊差异并不能证明更大的行为是合理的。)
我可以看到新行为的吸引力:没有两种退出主线程的方法(“退出并等待线程”和“立即退出”),只有一种,因为 sys.exit 本质上与简单相同从顶层函数返回。然而,这是一个重大变化,与记录的行为不同,这远远超过了这一点。
由于此更改,在上述信号处理程序的 sys.exit
之后,解释器等待线程退出,然后在线程退出后运行 atexit
处理程序。由于是处理程序本身告诉线程退出,结果是死锁。
关于python 2.6.x theading/signals/atexit 在某些版本上失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3713360/
我正在尝试在 Python 中运行一个简单的多进程应用程序。主线程生成 1 到 N 个进程并等待它们全部完成处理。每个进程都运行一个无限循环,因此它们可能会永远运行而不会受到用户的干扰,因此我放入了一
用atexit()注册的函数是最后执行的函数吗?有没有可能此时其他线程还在运行? 最佳答案 Are the functions registered with atexit() the last fu
我可以将常规函数指针传递给atexit(): void f1(void) { printf("f1\n"); } int main() { void (*fun_ptr)(void)
我可以将常规函数指针传递给atexit(): void f1(void) { printf("f1\n"); } int main() { void (*fun_ptr)(void)
是否可以注销退出处理函数??? void exit_handler_1() { printf("in first exit handler\n"); } int main() { if
我知道什么时候函数的地址传递给atexit函数, 该函数被执行。 #include int atexit(void (*func) void)); 但是,使用atexit函数的目的是什么? 词义本身
当我运行 python 脚本时,我可以退出解释器,并且 atexit 将执行我注册的所有函数。 现在,我正在使用 Airflow ,并希望触发 atexit 任务 on_kill() (即,当我清除或
在我的程序中,我使用了一个静态变量(没有其他办法),问题是它需要在退出时被释放。 如何在不必将此变量声明为全局变量的情况下实现这一点? 我在想atexit 函数,但它似乎不能带参数。有什么技巧可以传递
我有一个 C 程序在 Linux 上意外退出,我很难找出原因(没有核心转储,请参阅 XIO: fatal IO error 11)。我在程序的开头放置了一个 atexit() 并且当崩溃发生时确实调用
我想在需要时推送一系列清理功能。我使用 atexit 为一个没有任何参数的清理函数执行此操作,但我不确定如何将这种方法扩展到多个清理函数。我对 boost::bind 不是很熟悉,但我认为这是个好主意
在一个共享库中,函数 func1() 有 atexit(terminate_global) 而这个共享库没有 'attribute ((constructor))' 和 'attribute ((析构
我有两个 python 文件: a.py: import subprocess, time, os, signal myprocess = subprocess.Popen("b.py", shell
我正在用 C++ 编写调试器,退出时我需要它来清除在调试对象中设置的所有断点。 我制作了一个名为 BREAKPOINT_INFO 的 struct,其中包含清除每个断点所需的信息。进程句柄(hProc
有几个教程解释了 atexit() 函数的用法,例如: http://linux.die.net/man/3/atexit 例子在一个简单易懂的main函数中给出。但是,我在我的程序中创建了一个共享库
如果我将 atexit( fn ); 放在退出堆栈上,它将在程序退出时执行:从 main() 返回或通过 exit ()。 我可以将它从堆栈中移除吗? 你问我为什么要这样做? 我正在使用 atexit
在图书馆等大型项目中使用 atexit 是否存在固有的危险? 如果是这样,atexit 背后的技术本质是什么可能导致大型项目出现问题? 最佳答案 我避免在库中使用 atexit 的主要原因是它的任何使
我们遇到了一个问题,即第 3 方库使用 atexit() 注册了一些函数。有什么方法可以知道注册了多少(或哪些)功能? 我检查了here但它说不。 我尝试使用 sysconf 获取 ATEXIT_MA
有什么方法可以在 atexit 模块中注册并在退出时调用的函数中设置退出代码吗?调用 sys.exit(code) 会产生错误,并且不会将退出代码设置为所需的值。 d:\>python atexit_
关闭。这个问题是opinion-based 。目前不接受答案。 想要改进这个问题吗?更新问题,以便 editing this post 可以用事实和引文来回答它。 . 已关闭 7 年前。 Improv
我的代码工作得很好,但是当我退出 simpleshell 时,我遇到了段错误。 atexit(final) 的决赛仍然被调用并且正常工作。我认为问题出在 atexit() 上,因为当从代码中删除 at
我是一名优秀的程序员,十分优秀!