处理严重错误的方式是不友好的 exit() 吗?
Posted
技术标签:
【中文标题】处理严重错误的方式是不友好的 exit() 吗?【英文标题】:Is ungentle exit() acceptable way to handle critical error? 【发布时间】:2018-12-28 21:20:26 【问题描述】:在多线程C程序中,由于严重的程序错误,温和的程序退出真的很难实现,使用exit_group();
函数硬退出是否可以接受停止程序执行的方式?
我的意思是非常严重且不可恢复的错误,任何进一步的操作都可能损坏文件系统和数据库。我有点担心潜在的资源泄漏。事实上,甚至没有泄漏,而是锁定 - 因此该进程无法在不重新启动的情况下重新启动,因为某些资源将保持保留。
有问题的操作系统是现代 Linux(4.x 内核)
【问题讨论】:
这完全取决于 a) 您使用的操作系统和 b) 您使用的资源类型。许多资源在进程退出时自动释放和解锁,但其他资源可能会持续存在(例如 sysv shm/信号量,锁定文件等 pp)。例如,对于 sysv 信号量操作,您可以指定SEM_UNDO
以撤消进程退出时的操作
你关心什么样的锁?您是否使用任何类型的共享内存,或者锁定是否严格发生在被杀死进程中的线程之间?
@dbush 我最关心的是 inotify 手表和 sqlite 数据库。因为 FUSE 能很好地处理 ungentle crash。它旨在做到这一点。还有信号量和同步资源。
@Ctx 据我了解,当我使用多进程架构或只杀死一个线程时,我需要 SEM_UNDO
或 pthread_mutexattr_setrobust
吗?这样程序就不会出现死锁。但是如果程序是单个进程并且我正在杀死所有线程,我不需要强大的互斥锁吗?
@Lapsio 取决于您使用的是 pthread 互斥体还是 sysv 信号量。这是两种不同的机制。从你写的来看,带 SEM_UNDO 的 sysv 信号量看起来更合适
【参考方案1】:
exit
运行用atexit
或at_quick_exit
注册的清理处理程序,刷新stdio 流,并执行许多其他清理。对于真正严重的错误(例如潜在可利用的内存损坏),_exit
将是更安全的选择。在较旧的 glibc 版本中,abort
(或assert(false)
)也刷新了 stdio 流。另一种选择是执行未定义的指令。
【讨论】:
以上是关于处理严重错误的方式是不友好的 exit() 吗?的主要内容,如果未能解决你的问题,请参考以下文章
git did not exit cleanly (exit code 128)处理方式
git did not exit cleanly (exit code 128)处理方式