いいえ、特定のコードがアプリケーションの終了時に実行されることを保証する方法はありません。これは、アプリケーションがキャッチできない方法でユーザーがアプリケーションを終了する可能性があるためです (たとえば、デスクトップのプラグを抜くなど)。機械)。
あなたのコードは、予期せぬ終了に対して絶対に強化されなければなりません。
どの程度強化する必要があるかは、アプリによって異なります。ドキュメント ベースのアプリ (最新の自動保存頻度モデルより前) では、最後の保存後にデータが失われることが予想されていました (そして面倒でした)。
アプリでは、永続化のコストと永続化されたデータの価値のバランスを取る必要があります。
キャッチできる終了シグナルにのみ興味があります。
「捕まえられる」と「役に立つことならなんでもできる」は違います。お気づきのように、多くの信号をキャッチできます。
ただし、シグナル ハンドラでは実際には何もできません。技術的には、メモリを割り当てることさえできません。
同様に、シグナルまたは例外は通常、アプリケーションが未定義の致命的な破損状態に入ったために生成されます。したがって、アプリケーション内の内部状態が使用可能であることに期待することはできません。
クラッシュが発生したときにアプリがユーザーの状態を保存しようとして、破損した状態を非常に陽気に書き込んでしまい、最終的にユーザーが大幅に多くのデータを失うことになるケースを数多く見てきました。
フックが何をしようとしているのかを知っておくと役に立ちます。
詳細については、sigaction の man ページを参照してください。
具体的には、安全に呼び出せる関数のリストには、_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()、 utime()、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 現在実行中の機能を中断しています。
入力しようとしていたこと: シグナル ハンドラーはランダムなスレッドで配信される可能性があり、現在実行中の関数も中断する可能性があることに注意してください。つまり、アプリの状態は多少不確定である可能性があります。