不,没有办法保证任何给定的代码将在应用程序终止时执行,因为用户可能会以应用程序无法捕获的方式终止应用程序(例如,拔掉桌面上的插头机器)。
您的代码绝对必须针对意外终止进行强化。
你需要加强多少取决于你的应用程序。在基于文档的应用程序中(在现代经常自动保存模型之前),在上次保存后丢失数据是意料之中的(而且很烦人)。
对于您的应用程序,您需要平衡持久性成本与持久数据的价值。
我只对可以捕获的终止信号感兴趣。
“可以被抓住”和“可以做任何有用的事情”之间是有区别的。正如您所指出的,可以捕获许多信号。
但是,您真的不能在信号处理程序中做任何事情。从技术上讲,您甚至无法分配内存。
同样,通常会生成信号或异常,因为应用程序已进入未定义的、灾难性损坏的状态。因此,您不能指望应用程序中的任何内部状态都可用。
我见过很多情况,当崩溃发生时,应用程序会尝试保存用户状态,只是为了相当愉快地写入损坏状态,最终导致用户丢失更多数据。
知道你的钩子试图做什么会很有帮助。
有关更多信息,请参阅 sigaction 手册页。
具体来说,可以安全调用的函数列表包括 _exit()、access()、alarm()、cfgetispeed()、cfgetospeed()、cfsetispeed()、cfsetospeed()、chdir()、chmod()、chown( )、close()、creat()、dup()、dup2()、execle()、execve()、fcntl()、fork()、fpathconf()、fstat()、fsync()、getegid()、 geteuid()、getgid()、getgroups()、getpgrp()、getpid()、getppid()、getuid()、kill()、link()、lseek()、mkdir()、mkfifo()、open( ), pathconf(), pause(), pipe(), raise(), read(), rename(), rmdir(), setgid(), setpgid(), setsid(), setuid(), sigaction(), sigaddset(), sigdelset(), sigemptyset(), sigfillset(), sigismember(), signal(), sigpending(), sigprocmask(), sigsuspend(), sleep(), stat(), sysconf(), tcdrain( )、tcflow()、tcflush()、tcgetattr()、tcgetpgrp()、tcsendbreak()、tcsetattr()、tcsetpgrp()、time()、times()、umask()、uname()、unlink()、时间(),wait()、waitpid()、write()、aio_error()、sigpause()、aio_return()、aio_suspend()、sem_post()、sigset()、strcpy()、strcat()、strncpy()、strncat( )、strlcpy() 和 strlcat()。
上述列表中没有的所有函数都被认为对信号不安全。也就是说,从信号处理程序调用此类函数时的行为是未定义的。但总的来说,信号处理程序应该做的只是设置一个标志。大多数其他操作都不安全。
翻译:你真的不能在信号处理程序中做很多有用的事情。
Mpte a;sp tjat sogma; ,au ne de;overed pm amu tjread amd ,ogjt ne de;overed nu 中断当前正在执行的函数。
我的意思是:请记住,信号处理程序可能会在随机线程上传递,也可能会中断当前正在执行的函数。即您的应用程序的状态可能有些不确定。