我在C中实现了一个简单的迭代TCP客户端/服务器。服务器在循环中无限列出。
现在如果在任何时间点发生Ctrl + c(SIGINT),我如何释放服务器中使用的资源?
例如,我在自己的信号处理程序中捕获了信号;我如何获得套接字描述符 和程序中使用的缓冲区,以释放它们?
我是socket编程新手;任何建议将不胜感激。
答案 0 :(得分:2)
没有。传递给信号处理程序的唯一参数是int
,它是信号编号。
处理您描述的情况的典型方法是使用一个全局变量,例如您的循环正在检查的int stopAndExit
。如果它被信号处理程序翻转到1
,你知道要清理并退出。
修改:有关以下评论提示的更全面的讨论。
这个问题的一个问题是当信号到达时你是否处于不可重入的功能。为了解决这个问题,你实际上想要延迟(阻塞)信号,然后在主循环中的一个安全点处理它们。
上次编辑:除非您之前需要清理一些需要清理的外部操作,否则您可以保证退出清洁状态......这没关系。退出时,套接字描述符和缓冲区都会消失。没有必要清理任何东西。
答案 1 :(得分:2)
不要安装信号处理程序。什么都不做SIGINT
的默认操作是终止进程,并假设没有其他进程具有套接字的描述符,它们将自然地关闭并在进程终止时停止存在。
答案 2 :(得分:0)
这个答案中的代码非常不安全,会调用各种UB,不应该在你的情况下使用。在信号处理程序中使用setjmp
/ longjmp
只能作为处理空指针解引用的方式远程工作,即使这样,它也需要在范围上非常有限,以避免调用UB。
这是处理清理的另一种可能方式:
static jmp_buf buf;
static int ret = 0;
void handle(int sig)
{
ret = 1;
longjmp(buf, 1);
}
int func(void)
{
FILE *f = fopen(/* yadda */);
void (*orig)(int) = signal(SIGINT, handle);
if(setjmp(buf)) goto CLEANUP;
// use f
CLEANUP:
fclose(f);
signal(SIGINT, orig);
return ret;
}
当然,在信号处理程序中做很多艰苦工作并不能保证符合标准,但我确定你是否担心你不会试图处理信号。