我正在C中实现一个简单的迭代TCP客户端/服务器。服务器无限地在循环中列出。我们可以将参数传递给C中的信号吗?
现在,如果在任何时间点出现Ctrl + c(SIGINT),我将如何释放服务器中使用的资源?
例如,我在我自己的信号处理程序中捕获到信号;我将如何获取套接字描述符 和程序中使用的缓冲区以释放它们?
我是socket编程的新手,任何建议,将不胜感激。
我正在C中实现一个简单的迭代TCP客户端/服务器。服务器无限地在循环中列出。我们可以将参数传递给C中的信号吗?
现在,如果在任何时间点出现Ctrl + c(SIGINT),我将如何释放服务器中使用的资源?
例如,我在我自己的信号处理程序中捕获到信号;我将如何获取套接字描述符 和程序中使用的缓冲区以释放它们?
我是socket编程的新手,任何建议,将不胜感激。
请勿安装信号处理程序。不要做任何事情。 SIGINT
的默认操作是终止进程,并且假设没有其他进程为您的套接字使用描述符,那么当进程终止时,它们都将自然关闭并停止存在。
+1因为我们都在一个不适用于他的问题的切线上。尽管他选择了你的答案,你欠我一个。 :-p – 2011-03-14 05:43:35
我非常确定这一点,但是在标准中查找时仍然侧目。 – 2011-03-14 05:50:47
@Brian:够公平的。如果OP接受我的答案,请在答案上+1。 :-) – 2011-03-14 06:00:00
否。传递给您的信号处理程序的唯一参数是int
这是信号编号。
处理您描述的情况的典型方法是使用您的循环正在检查的全局变量,例如int stopAndExit
。如果它被信号处理程序翻转到1
您知道清理并退出。
编辑:欲了解更多详情,请参阅下面的评论。
这样做的一个问题是,如果您在信号到达时处于非重入函数。为了解决这个问题,你实际上想延迟(阻塞)信号,然后在主循环中一个安全的地方处理它们。
最后编辑:除非您有一些外部操作需要清理之前,因此您保证以干净的状态退出,这并不重要。无论如何,当你退出时,你的套接字描述符和缓冲区都会消失。没有必要清理任何东西。
这个答案中的代码是可怕的不安全的,调用各种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;
}
当然,做了一大堆的拼搏,信号处理程序不能保证通过该标准的工作,但我敢肯定如果你担心你不会尝试处理信号。
这是另一个很好的解决方案,我真的很担心释放它们...... – Muse 2011-03-14 05:06:17
该解决方案调用非常危险的未定义行为。 – 2011-03-14 05:34:13
为了澄清,你的'fclose(f)'在一个'FILE'上运行,其状态几乎肯定不一致(IO期间信号中断的最高概率时间)。这不仅仅是“标准不能保证”的工作。 – 2011-03-14 05:57:35
你刚开始使用全局变量!有时候,它们实际上是有用的,与许多人会想到的相反...... – 2011-03-14 04:42:00
@Carl:不,这只是一个信号处理程序是处理输入的糟糕方法的标志。 – 2011-03-14 05:20:11
@R ..或许这是一场半满半场的争吵? (顺便说一下,我同意你们两个的意见。) – 2011-03-14 05:21:32