c++多线程学习笔记一——多线程相关概念及简单的示例函数

这篇博客介绍了C++中创建线程的基本方法,包括通过函数、类对象以及类成员函数指针创建线程,并探讨了线程间通信和参数传递的不同方式,如值传递和引用传递。此外,还讨论了线程所有权的转移和批量创建线程的概念。
摘要由CSDN通过智能技术生成

进程:
可以简单理解成一个可执行程序

线程:
一个进程可以包含多个线程,一定有一个主线程。

进程与线程之间的区别与联系:
1)进程是最小的资源分配单位,线程是最小的程序执行单位,每新建立一个进程,系统需要为其分配相应的地址空间,而线程共享数据段,是同一个地址空间,CPU切换一个线程要比切换一个进程花费小很多。
2)进程之间的通信不是很方便,比如经历SOCKET之类的网络编程技术,而线程之间因为是共享数据段所以线程之间的通信很方便很多。
3)多进程程序具有健壮性,具有一定的稳定性,多线程程序只要有一个程序崩溃,整个程序崩溃,而多进程一个程序崩溃,其他程序依然可以保持独立运行。

创建线程的几种方式

一 、简单的线程函数

# include<iostream>
# include<thread> //引入多线程包含的头文件
using namespace std;
//线程函数
void print_hello()
{
	cout << "我的线程开始了 " << endl;
	//......
	cout << "我的线程结束了 " << endl;
}
int main()
{
	std::thread study_1(print_hello);//创建一个新的线程并开始执行,主线程继续向下执行同时也开始执行线程函数中的内容
	
	cout << "这里是主线程 " << endl;
	study_1.join();//主线程执行到此处后,需要等待线程函数执行完毕,
}

二、将类对象作为线程函数,重载(),初始化类对象将其作为线程函数

# include<iostream>
# include<thread> //引入多线程包含的头文件
using namespace std;
//线程函数
void print_hello()
{
	cout << "我的线程开始了 " << endl;
	//......
	cout << "我的线程结束了 " << endl;
}
class Thread_function
{
public:
	void operator()()
	{
		cout << "创建一个线程 " << this_thread::get_id() << endl;
		cout << "线程函数执行完毕 " << endl;
	}
};
int main()
{
	std::thread study_1(print_hello);//创建一个新的线程并开始执行,主线程继续向下执行同时也开始执行线程函数中的内容
	//初始化类对象
	Thread_function get_id;
	std::thread study_2(get_id);
	
	study_1.join();//主线程执行到此处后,需要等待线程函数执行完毕。
	study_2.join();//主线程执行到此处后,需要等待线程函数执行完毕。
	cout << "这里是主线程 " << endl;
}

三、将某个类中某个函数当作线程函数,初始化类对象以后,第一个参数是对象中的线程函数,第二个函数是类对象名称,需要在前面都加上&。

# include<iostream>
# include<thread> //引入多线程包含的头文件
using namespace std;
//线程函数
void print_hello()
{
	cout << "我的线程开始了 " << endl;
	//......
	cout << "我的线程结束了 " << endl;
}
class Thread_function
{
public:
	void operator()()
	{
		cout << "创建一个线程 " << this_thread::get_id() << endl;
		cout << "线程函数执行完毕 " << endl;
	}
	void Thread_function_1();
};
void Thread_function::Thread_function_1()
{
	cout << "将类中的函数作为线程函数,创建一个线程 " << this_thread::get_id() <<endl;
	cout << "类中函数作为线程函数  "<< endl;
	
}
int main()
{
	std::thread study_1(print_hello);//创建一个新的线程并开始执行,主线程继续向下执行同时也开始执行线程函数中的内容
	//初始化类对象
	Thread_function get_id;
	std::thread study_2(get_id);
	
	
	std::thread study_3(&Thread_function::Thread_function_1,&get_id);


	study_1.join();//主线程执行到此处后,需要等待线程函数执行完毕。
	study_2.join();//主线程执行到此处后,需要等待线程函数执行完毕。
	study_3.join();//主线程执行到此处以后,需要等待线程函数执行完毕,
	cout << "这里是主线程 " << endl;
}

向线程函数中传递参数

1)向线程函数传递参数可以在初始化对象的时候,在线程函数后面添加函数参数即可
2)默认线程函数参数传递是值传递,想要传引用,在需要在传参数中加入ref(),并且线程函数要加引用符号。
3)普通引用时候前面需要加const限定符,因为源码初始化的时候是右值引用因此要加const。
4)当类成员函数指针作为线程函数时,可以直接更改对象的数据,与引用的意义相同,若需要参数则在对象后面添加。

void changebyref( int& a)
{
	a++;
}
void changebyref( int& a)
{
	a++;
}
int main()
{   
	int num = 1;
	std::thread function1(changebyref, ref(num));
	cout << "nums is " << num << endl;
	function1.join();
	cout << "nums is " << num << endl;
}

类成员函数指针作为线程函数

class Thread_function
{
	int a;
	int b;
public:
	void set_a(int a_) { a = a_; }
	void set_b(int b_) { b = b_; }
	void sum() { cout << "值为 " << a + b << endl; }
	Thread_function(int a_ = 0, int b_ = 0) :a(a_), b(b_)
	{}
};
int main()
{   
	Thread_function rui;
	std::thread fun_1(&Thread_function::set_a, &rui,20);
	std::thread fun_2(&Thread_function::set_b, &rui,20);
	fun_1.join();
	fun_2.join();
	rui.sum();
}

批量创建线程以及线程所有权的转移

void count1(int a)
{
	cout << "此时的a 是 " << a << endl;
}
int main()
{   
	vector<thread> More_thread;
	for (int i = 0; i <= 9; i++)
	{
		More_thread.push_back(std::thread(count1,i));
	}

	for (int i = 0; i < More_thread.size(); i++)
	{
		More_thread[i].join();
	}

}

转移线程所有权使用Move

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值