aiQG's Blog

Happy hacking. Happy developing.

aiQG's GitHub ⛓Links P
Other CTF Swift Developing & Reversing

C++线程+匿名函数(lambda表达式) 入门

4 April 2019

by aiQG_

#include <iostream>
#include <thread>
using namespace std;
//这是线程要执行的函数
void hellofun(int i)
{
    cout<<"Helloworld\t"<<i<<endl;
    	return;
}
//main函数相当于主线程
int main()
{
	    for(int i=0; i<10;i++)
	    {
        		thread THR1(hellofun, i);
        		THR1.join();
        		//THR1.detach();
	    }
    	return 0;
}

hellofun(int i) 将会被线程执行//相当于线程的main函数 thread THR1(hellofun, i) 是声明了一个叫做THR1的线程,线程将会在被声明后立即执行,hellofun 是要执行的函数名(没想到吧函数名还能这么用),函数名后面的参数就是函数的参数(hellofun的参数) thread thrName(Fun, a, b, c, ...); 那么问题来了有时候我们想让线程一起跑(并行),有时想让它们排排队,一个一个跑(串行)又要怎么实现呢 这就涉及到线程的两个方法: detach() 方法让线程并行,不会阻塞主线程的运行 join() 方法让线程串行,主线程会等待线程的结束 调皮的小朋友又要问了:如果两个方法都用会发生什么? 五号机:当然是报错了 调皮的小朋友又要问了:那我最多可以创建多少线程呢? 那我们把程序改一改,再跑跑看

#include <iostream>
#include <thread>//线程,C++11
using namespace std;
void hellofun(int i)
{
    cout<<"Helloworld\t"<<i<<endl;
    	while(1);//
    	return;
}
int main()
{
    	for(int i=0; ;i++)
    	{
        		thread THR1(hellofun, i);
        		THR1.detach();
        		//THR1.join();
    	}
    	return 0;
}

好的 现在调皮的小朋友被卡死了,我们继续。 我们创建的线程都说main函数的子线程,会在main函数return后挂掉//当然有不让它挂掉的方法 线程还有很多的方法,可以实现很多功能具体的百度去吧~


我们创建线程必须要编写一个函数作为线程的”主函数”,这就不免要有函数的声明,定义…写起来不仅麻烦,线程执行了什么内容也不能一目了然。于是C++11又送来了一个新特性:拉姆达表达式 lambda表达式。 有了lambda表达式,我们上面的程序就可以这样写了

#include <iostream>
#include <thread>
using namespace std;
int main()
{
    	for(int i=0; i<10; i++)
    	{
		        thread THR1([](int i){
		            cout<<"Helloworld\t"<<i<<endl;					
		        }, i);
		        THR1.detach();
		        //THR1.join();
    	}
    	return 0;
}

看懂了么?我们把hellofun换成了

[](int i){cout<<"Helloworld\t"<<i<<endl;}

它没有名字(匿名)了!

匿名函数是个神奇的东西,它配合auto用似乎又可以有名字

auto fun = [](){cout<<"helloworld!"<<endl;};
	fun();
	//helloworld!

但是外部的变量对于匿名函数并不是可见的

int a = 666;
	auto fun = [](){cout<<"helloworld!"<<a<<endl;};//这里编译器会说不知道a是什么
	fun();

要想使用外部变量就要修改中括号部分: []:默认不捕获任何变量; [=]:默认以值捕获所有变量; [&]:默认以引用捕获所有变量; [x]:仅以值捕获x,其它变量不捕获; [x,y,z]:仅以值捕获x,y,z,其它变量不捕获; [&x]:仅以引用捕获x,其它变量不捕获; [=, &x]:默认以值捕获所有变量,但是x是例外,通过引用捕获; [&, x]:默认以引用捕获所有变量,但是x是例外,通过值捕获; [this]:通过引用捕获当前对象(其实是复制指针); [*this]:通过传值方式捕获当前对象;

关于lambda表达式,也可以看看这篇文章: https://www.jianshu.com/p/d686ad9de817

//C++的lambda表达式同时用到了大括号中括号小括号,真帅!

Other

return

email:nrxxmzlrovqw4z3fgeztcncaozuxaltroexgg33n