Lambda表达式,可以方便的定义和创建匿名函数。 此帖介绍一下lambda与多线程之间的关系。
创建一个多线程用例
#include <chrono>
#include <iostream>
#include <thread>
void thread_task(int n) {
std::this_thread::sleep_for(std::chrono::seconds(n));
std::cout << "hello thread "
<< std::this_thread::get_id()
<< " paused " << n << " seconds" << std::endl;
}
int main(int argc, const char *argv[])
{
std::thread threads[5];
std::cout << "Spawning 5 threads...\n";
for (int i = 0; i < 5; i++) {
threads[i] = std::thread(thread_task, i + 1);
}
std::cout << "Done spawning threads! Now wait for them to join\n";
for (auto& t: threads) {
t.join();
}
std::cout << "All threads joined.\n";
return 0;
}
lambda与多线程
常见的lambda结构 其中:
- 格式1声明了const类型的表达式,这种类型的表达式不能修改捕获列表中的值。
- 格式2省略了返回值类型,但编译器可以根据以下规则推断出Lambda表达式的返回类型: (1):如果function body中存在return语句,则该Lambda表达式的返回类型由return语句的返回类型确定; (2):如果function body中没有return语句,则返回值为void类型。
- 格式3中省略了参数列表,类似普通函数中的无参函数。
下面举一个实例
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
bool cmp(int a, int b)
{
return a < b;
}
int main()
{
vector<int> myvec{ 3, 2, 5, 7, 3, 2 };
vector<int> lbvec(myvec);
sort(myvec.begin(), myvec.end(), cmp);
cout << "predicate function:" << endl;
for (int it : myvec)
cout << it << ' ';
cout << endl;
sort(lbvec.begin(), lbvec.end(), [](int a, int b) -> bool { return a < b; });
cout << "lambda expression:" << endl;
for (int it : lbvec)
cout << it << ' ';
}
捕获外部变量
lambda函数还可以使用其可见范围内的外部变量,但是必须声明。相关实例:C++ 11 Lambda表达式
多线程实例
#include <iostream>
#include <thread>
#include <vector>
int main() {
std::cout << "Hello, World!" << std::endl;
std::vector<std::thread> m_thread;
for(int i=0; i<4; i++)
m_thread.emplace_back([i](){
int cnt = 0;
while(1) {
std::this_thread::sleep_for(std::chrono::seconds(i));
std::cout << "hello thread "
<< std::this_thread::get_id()
<< " paused " << i << " seconds" << std::endl;
if(cnt++ > 3)
break;
}
});
std::cout << "Done spawning threads! Now wait for them to join\n";
for (auto& t: m_thread) {
t.join();
}
std::cout << "All threads joined.\n";
return 0;
}
与原多线程实例的区别,emplace_back可以直接输入参数进行元素原地构造(参考emplace_back() 和 push_back 的区别)。所以在此实例中,lambda的仿函数对应的thread_task()函数,参数可以从[]进行传入。
|