2011-03-14 139 views
0

我正在C中实现一个简单的迭代TCP客户端/服务器。服务器无限地在循环中列出。我们可以将参数传递给C中的信号吗?

现在,如果在任何时间点出现Ctrl + c(SIGINT),我将如何释放服务器中使用的资源?

例如,我在我自己的信号处理程序中捕获到信号;我将如何获取套接字描述符 和程序中使用的缓冲区以释放它们?

我是socket编程的新手,任何建议,将不胜感激。

+2

你刚开始使用全局变量!有时候,它们实际上是有用的,与许多人会想到的相反...... – 2011-03-14 04:42:00

+0

@Carl:不,这只是一个信号处理程序是处理输入的糟糕方法的标志。 – 2011-03-14 05:20:11

+0

@R ..或许这是一场半满半场的争吵? (顺便说一下,我同意你们两个的意见。) – 2011-03-14 05:21:32

回答

2

请勿安装信号处理程序。不要做任何事情。 SIGINT的默认操作是终止进程,并且假设没有其他进程为您的套接字使用描述符,那么当进程终止时,它们都将自然关闭并停止存在。

+1

+1因为我们都在一个不适用于他的问题的切线上。尽管他选择了你的答案,你欠我一个。 :-p – 2011-03-14 05:43:35

+0

我非常确定这一点,但是在标准中查找时仍然侧目。 – 2011-03-14 05:50:47

+0

@Brian:够公平的。如果OP接受我的答案,请在答案上+1。 :-) – 2011-03-14 06:00:00

2

否。传递给您的信号处理程序的唯一参数是int这是信号编号。

处理您描述的情况的典型方法是使用您的循环正在检查的全局变量,例如int stopAndExit。如果它被信号处理程序翻转到1您知道清理并退出。

编辑:欲了解更多详情,请参阅下面的评论。

这样做的一个问题是,如果您在信号到达时处于非重入函数。为了解决这个问题,你实际上想延迟(阻塞)信号,然后在主循环中一个安全的地方处理它们。

最后编辑:除非您有一些外部操作需要清理之前,因此您保证以干净的状态退出,这并不重要。无论如何,当你退出时,你的套接字描述符和缓冲区都会消失。没有必要清理任何东西。

+0

所以我也需要使套接字描述符全局释放他们..... – Muse 2011-03-14 04:44:41

+0

嗯,不。所有这些都可用于您的主服务器环路。每次循环时只需检查'stopAndExit'全局。当它看到它应该停止并退出时,它会清理干净,然后退出。 – 2011-03-14 04:47:27

+0

@Brian:所以我认为这是做它的唯一方法....... – Muse 2011-03-14 04:52:21

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; 
} 

当然,做了一大堆的拼搏,信号处理程序不能保证通过该标准的工作,但我敢肯定如果你担心你不会尝试处理信号。

+0

这是另一个很好的解决方案,我真的很担心释放它们...... – Muse 2011-03-14 05:06:17

+0

该解决方案调用非常危险的未定义行为。 – 2011-03-14 05:34:13

+1

为了澄清,你的'fclose(f)'在一个'FILE'上运行,其状态几乎肯定不一致(IO期间信号中断的最高概率时间)。这不仅仅是“标准不能保证”的工作。 – 2011-03-14 05:57:35

相关问题