2011-05-21 106 views
8

在C中,如果我的应用程序意外结束,我可以在这之前调用函数吗?我正在向数据库写入一个标志(processRunning = 1),以防止其他应用程序启动类似的进程。当应用程序结束时,它不会将该标志改回。C:程序退出时做些什么

回答

6

查看C标准库的API atexit

+0

现货。谢谢。 – 2011-05-21 14:15:40

+3

这不是一个解决方案。它不会保护您免受异常终止。 'atexit'函数在实践中基本没有用处,除了小程序永远不会变大或变成图书馆之外,它的使用应该被认为是有害的,因为它必然涉及全局变量/全局状态。 – 2011-05-21 14:54:42

+2

你们都可能已经知道这一点,但网络中断和电源故障等事情可能会阻止这类代码的运行。每隔'n'分钟向数据库写入时间戳可能会更加健壮,并且在没有时间戳记的'n + m'分钟后让数据库清理废弃的标记。 – 2011-05-21 14:56:39

4

如果您的应用程序正常终止,它将运行通过atexit注册的函数。这是标准功能,可在Windowsunix和其他所有平台上获得,也可在C++中获得。

请注意,“正常终止”是指通过致电exit()或从main()返回。如果您的申请通过abort()_exit()终止,或者如果它从外部被立即杀害,它可能没有机会做任何清理。可能会有更好的方法,可能会设置和清除包装程序中的标志,无论程序如何终止,或者完全取消该标志,都会进行清理。

+0

感谢您的额外建议,Gilles。我正在考虑某事。类似于每隔几秒检查一次应用程序是否连接到特定PID的进程仍在运行。 – 2011-05-21 14:15:33

+0

一个解决方案可能是涉及捕获信号。 (我认为这不适用于Windows。) – 2011-05-21 14:16:48

+1

@Frank:当心PID检查并非万无一失。 PID可以被不相关的进程快速重用。 – Gilles 2011-05-21 14:17:41

2

有更好的方法来阻止应用程序运行两次。一种解决方案是使用系统范围内名为互斥体的。另一个也许更简单的解决方案是锁定一个文件(开放写入)。即使应用程序崩溃资源被操作系统释放,您将能够再次启动应用程序,因为文件或互斥锁不会再被锁定。

5

在POSIX上,正确的解决方案是使用共享内存中的强大互斥锁来保护数据。如果你的进程死于一个强大的互斥体,另一个试图锁定互斥体的程序将不会发生死锁,而是返回EOWNERDEAD,然后它有机会清除由互斥体保护的状态并呼叫pthread_mutex_consistent

编辑:如果您只想防止程序的多个实例运行,那么确实有更好/更简单的方法,例如对数据库文件进行锁定。

+0

+1不知道。谢谢,弗兰克 – 2011-05-21 15:15:29