我有一个函数,它可以从网络上做一些免费和unregs:
void UNREG_on_exit(COT_arguments args, Node_Information *node)
我试图让它在我退出程序的时候被调用(即使使用Ctrl+C)
问题是我如何传递参数?从来没有做过函数指针,也不能真正找到答案。
目前我有:
void UNREG_on_exit(args, &node); // This is how you make the pointer?
atexit(UNREG_on_exit);
// or //
atexit((void) {
UNREG_on_exit(args, &node); // Or like this?
});
我不知道,他们两个都给予了我一个错误。
“需要标识符”,参数下的一条红线
其他信息:
typedef struct Node_Information
{
int id;
int net;
Backup bck;
Extern ext;
Intern *intern_list;
int InNetword;
int debug_mode;
int IsREGED;
int fd;
Table *table_list;
StringList *contents_list;
PendingConnections *pending_connections_list;
QueryList *query_list;
} Node_Information;
typedef struct COT_arguments
{
char *IP;
int TCP;
char *reg_IP;
int reg_UDP;
} COT_arguments;
4条答案
按热度按时间z0qdvdin1#
由
atexit
注册的函数不能带参数。它的签名必须是void (*)(void)
,即一个不返回任何参数的函数。你需要使用全局变量,这些变量在程序中的其他地方被设置,函数可以使用。
i34xakig2#
atexit
不支持带参数的函数,所以你既不能注册这样一个函数,也不能给它传递任何参数。你必须传递一个void(*)(void)
类型的函数指针-不带参数,不返回值。因此,必须通过一些其他方法来处理该部分,例如,使用文件范围变量。与任何像这样使用“回调函数”一样,要注意不要使用任何指向本地数据的指针,而只使用指向静态存储或动态分配内存的指针。
还要注意,
atexit
调用函数的顺序与FIFO相反,也就是说,最后注册的函数将首先执行。示例:
输出顺序由ISO C:
hmmo2u0o3#
我有一个函数,它可以从网络上做一些免费和unregs:
我试图让它在我退出程序的时候被调用(即使使用Ctrl+C)
帧挑战:为什么?
特别是为什么要担心在程序退出时释放分配的内存,因为无论您是否显式释放它,系统都会释放它。它还将关闭进程的打开文件,包括网络连接。这可能不会产生与远程网络服务的干净的应用程序级断开连接,但任何此类服务都需要对此类事件具有鲁棒性。
我写过很多软件,但我不记得曾经注册过退出处理程序。我安排在程序进行时在适当的点清理资源,并在正常终止时显式地执行任何最终清理。这比使用退出处理程序更清楚,也不那么神秘。我很少看到需要制定特殊的规定来处理异常终止。而且不可能处理 * 所有 * 异常终止。即使没有无法捕获或处理的致命信号,也没有针对突然断电或灾难性硬件故障的软件级保护。
但是如果你坚持尝试处理异常终止,那么你将需要更加努力地工作。标准
atexit()
和特定于GNU的on_exit()
注册的退出处理程序在 * 正常 * 程序终止时运行,这意味着当exit()
函数被调用或对main()
的初始调用返回时。当进程被信号杀死时,它们不会运行(这是Ctrl+C产生的一种术语),或者当它由于调用_exit()
或_Exit()
而终止时,或者当它停止运行而不终止时,例如通过调用execve()
。你可能可以避免调用
_Exit()
和其他有问题的函数,但是要在接收到信号时进行清理,你需要为 * 所有 * 默认处理是终止程序的信号注册一个信号处理程序。或者至少为那些可以被捕获的信号注册一个信号处理程序,这不是所有的信号。此外,信号处理程序可能只调用异步信号安全函数,我不确定你的“unregs”需要什么,所以也许这些都可以,但是free()
不是async-signal-safe的。exit()
也不是,以免你认为你可以调用它来将异常终止转换为正常终止。至于**使用
atexit()
**处理正常终止情况的细节,atexit()
的签名是因此,函数指针参数应该指向一个没有参数也不返回任何东西的函数,这就是它的调用方式。这样一个函数所处理的任何数据都必须是全局范围的(全局变量,环境变量,进程自己的PID,...)或可被该函数发现的(一天中的时间,某个已知目录中的文件,...)。示例:
您的特定C实现可能会提供其他替代方案,例如 * GNU特定的 *
on_exit()
。这些细节会有所不同。on_exit()
本身允许您注册数据指针沿着回调指针,以便在调用函数时传递给函数。这就是您向该函数提供数据的方式,但请注意,数据必须具有静态存储期限。否则当调用exit处理程序时,它的生存期已经结束。例如:unguejic4#
on_exit(3)
是你要找的。