使用Auto和Lambda处理信号? [英] Using Auto and Lambda to handle Signal?

查看:178
本文介绍了使用Auto和Lambda处理信号?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我编写了具有主要功能的程序,在其中创建了两个套接字,如下所示:

I have written this program that has a main function, inside which, I am creating two sockets, like this:

int sockfd1 = socket(AF_INET, SOCK_STREAM, 0);
int sockfd2 = socket(AF_INET, SOCK_STREAM, 0);

现在我用它们做一些事情,当用户按Ctrl + C终止进程时,我要确保套接字正确关闭,所以我这样做:

Now I do some stuff with them, and when the user presses Ctrl+C to terminate the process, I want to make sure the sockets close properly, so I do this:

auto sigTermHandler = [&] (int param) { close(sockfd1); close(sockfd2); };
signal(SIGTERM, sigTermHandler);

但是当编译为g++ -std=gnu++0x <filename>.cpp时,会引发以下编译错误:

But this throws the following compilation error when compiled as g++ -std=gnu++0x <filename>.cpp:

error: cannot convert ‘main(int, char**)::<lambda(int)>’ to ‘__sighandler_t {aka void (*)(int)}’ for argument ‘2’ to ‘void (* signal(int, __sighandler_t))(int)’

是否可以通过这种方式使用lambda处理信号?请告知.

Is it not possible to use lambda this way to handle signals? Please advise.

P.S.我知道,如果我执行适当的OOP,可以将其放入析构函数中,但我很想知道这是否可行.

P.S. I know I could put that in a destructor, if I did proper OOP, but I am curious to see if this works.

推荐答案

调用简单的函数指针时,不能使用lambda的捕获功能.该标准指出,没有捕获的lambda函数可以转换为函数指针,但是:

You cannot use the capture feature from lambda when calling a simple function pointer. The standard states that a lambda function without a capture is convertible to a function pointer, though:

5.1.2(6)没有lambda捕获的lambda表达式的闭包类型具有公共非虚拟非显式const 将函数转换为指向与闭包类型具有相同参数和返回类型的函数的指针 函数调用运算符.此转换函数返回的值应为函数的地址 在调用时,与调用闭包类型的函数调用运算符具有相同的作用.

5.1.2 (6) The closure type for a lambda-expression with no lambda-capture has a public non-virtual non-explicit const conversion function to pointer to function having the same parameter and return types as the closure type’s function call operator. The value returned by this conversion function shall be the address of a function that, when invoked, has the same effect as invoking the closure type’s function call operator.

例如,这有效:

signal(SIGTERM, [](int signum) { /* ... */ });

但不是这样:

signal(SIGTERM, [foo](int signum) { /* use foo here */ });

您实际上可以将sockfd1sockfd2保留为全局变量,然后可以在lambda函数中使用它们.但这显然不是一个好的设计.因此,最好使用 RAII 设计.如果程序终止,则套接字将始终关闭(如@Dani所指出的那样).

You could actually keep sockfd1 and sockfd2 as global variables and then, you could use them in the lambda function. But that is clearly not a good design. So it is better to use a RAII design. And if the program is terminated the sockets will be closed anyway (as @Dani is pointing out).

这篇关于使用Auto和Lambda处理信号?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆