我在 C 上撰寫網路函式,后臺執行緒中的 HTTP 請求,在接收 HTTP 資料時使用 lambda 回呼。但我不知道如何釋放 lambda,希望有所幫助。
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;
}
uj5u.com熱心網友回復:
您可以在 lambda 中捕獲 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 ?
}
或者如果它應該被共享,您可以通過 shared_ptr 使用共享所有權語意,然后按值將其捕獲到 lambda 中以增加其參考計數:
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();
}
對于非捕獲 lambda,可以將其轉換為函式指標,而不必真正關心
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();
uj5u.com熱心網友回復:
func必須是異步的堆變數。
您首先不應該談論堆和堆疊,而是談論存盤持續時間。這才是真正重要的。堆和堆疊是實作如何解決此問題的實作細節。
在許多情況下,通過參考 ( [&]) 為 lambda 捕獲所有內容是一個壞主意,因為您盲目地說要通過參考使用范圍內的所有內容。相反,您應該始終明確說明要通過參考捕獲什么以及通過副本捕獲什么。特別是在 lambda 的生命周期可能超過它可以參考的變數的情況下。
對于顯示的代碼,不清楚為什么func是在執行緒之外以及為什么它有[&]。兩者結合表明您稍后想要訪問捕獲的變數,然后您只是將整個問題移到了不同??的位置。
在當前形式中,您只需將代碼更改為:
#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;
}
但是,對于一個復雜的示例,您確實需要func在執行緒之外并且您可能需要使用存盤在func其中的 lambda 中的一些變數,這些變數是在其外部定義的,您需要添加捕獲以及您希望如何捕獲那里的東西取決于確切的用例。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/413486.html
標籤:
下一篇:GNUstep
