Estoy codificando una función de red en C ++, la solicitud HTTP en el hilo de fondo, use la devolución de llamada lambda cuando reciba datos HTTP. Pero no se como liberar la lambda, espero alguna ayuda.
void foo() { // the `func` must be a heap variable for asynchronously. auto func = new auto ([&](std::string response){ printf("recv data: %s", response.c_str()); }); std::thread t([&]{ sleep(2); // simulate a HTTP request. std::string ret = "http result"; (*func)(ret); }); t.detach(); // The foo function was finished. bug `func` lambda still in memory ? } int main() { foo(); getchar(); // simulate UI Event Loop. return 0; }Puede capturar lambda dentro de una lambda:
void foo() { std::thread t( [func = [](std::string response) { printf("recv data: %s", response.c_str()); }](){ sleep(2); // simulate a HTTP request. std::string ret = "http result"; func(ret); }); t.detach(); // The foo function was finished. bug `func` lambda still in memory ? }o si se supone que debe compartirse, puede usar la semántica de propiedad compartida a través de shared_ptr y luego capturarlo en la lambda por valor para aumentar su recuento de referencia:
void foo() { auto lambda = [](std::string response){ printf("recv data: %s", response.c_str()); }; std::shared_ptr<decltype(lambda)> func{ std::make_shared<decltype(lambda)>(std::move(lambda)) }; std::thread t([func]{ sleep(2); // simulate a HTTP request. std::string ret = "http result"; (*func)(ret); }); t.detach(); }Para lambdas que no capturan, uno puede convertirlo en un puntero de función y realmente no importa
void foo() { auto func_{ [](std::string response){ printf("recv data: %s", response.c_str()); } }; std::thread t([func=+func_]{ //note the + to turn lambda into function pointer sleep(2); // simulate a HTTP request. std::string ret = "http result"; (*func)(ret); }); t.detach();la
funcdebe ser una variable de montón para asincrónicamente.
En primer lugar, no debe hablar sobre el montón y la pila, sino sobre la duración del almacenamiento. Esto es lo realmente importante. Heap y stack son detalles de implementación de cómo la implementación resuelve esto.
Capturar todo por referencia ( [&] ) para lambda es en muchos casos una mala idea porque dices ciegamente que quieres usar todo en el alcance por referencia. En su lugar, siempre debe ser explícito sobre lo que desea capturar por referencia y por copia. Especialmente en el caso de que la vida útil de la lambda exceda las variables a las que puede hacer referencia.
Para el código que se muestra, no está claro por qué la func está fuera del hilo y por qué tiene [&] . Ambos combinados indican que luego desea acceder a una variable capturada, y luego simplemente movió el problema general a un lugar diferente.
En el formulario actual, simplemente podría cambiar su código a:
#include <thread> #include <cstring> #include <string> #include <unistd.h> void foo() { // removed & to not capture any variables auto func = [](std::string response){ printf("recv data: %s", response.c_str()); }; // replaced & by func to copy the lambda std::thread t([func]{ sleep(2); // simulate a HTTP request. std::string ret = "http result"; func(ret); }); t.detach(); } int main() { foo(); getchar(); // simulate UI Event Loop. return 0; } Sin embargo, para un ejemplo complejo donde realmente necesita func fuera del hilo y donde probablemente necesite usar algunas variables en la lambda almacenada en func que están definidas fuera de él, necesita agregar una captura y cómo desea capturar el las cosas allí dependen del caso de uso exacto.