我们可以将参数传递给C中的信号吗?

时间:2011-03-14 04:34:21

标签: c sockets signals

我在C中实现了一个简单的迭代TCP客户端/服务器。服务器在循环中无限列出。

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

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

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

3 个答案:

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

当然,在信号处理程序中做很多艰苦工作并不能保证符合标准,但我确定你是否担心你不会试图处理信号。