C++多线程的创建与使用(基础使用)

  • Post author:
  • Post category:其他




线程和进程的区别:

进程简单的来说就是一个exe的运行 线程是进程中一个代码片段的执行,线程内存分配的最小单位



并行:

一个进程中可以有多个线程 线程之间的运行可以并行



多线程之间如何进行同步或消息传递:

同一个电脑中的线程可以通过全局变量,内存管理进行同步 不同电脑之间可以使用socket通信进行线程同步



C++多线程的创建:

包含C++线程类 thread

  1. 普通函数创建线程
  2. 通过类和对象创建线程
  3. Lambda表达式创建线程
  4. 带参的方式创建线程
  5. 带智能指针方式创建线程
  6. 通过类成员函数创建线程



线程调用方法与注意事项


1.join(); 方法调用线程然后阻塞主线程,等待子线程执行完毕主线程才会执行


2.

detch();方法调用线程是与主线程并行,并不阻塞主线程,但是也和主线程是否执行完毕无关


3.

判断线程是否调用过可以使用线程对象的joinable()方法进行判断


4.

线程获取ID的方法可以在线程函数中使用静态方法 this_thread::get_id() 来获取线程ID


5.

带参的线程创建是需要使用std::ref()方法修饰参数


6.

指针只能使用move移动,但是需要注意移动后指针内存地址会被清空。



普通函数创建线程 **



#include <iostream>
#include <thread>
using namespace std;

void print()
{
	cout << "普通函数线程\t ID:"<<this_thread::get_id() << endl;
	return;
}

int main1()
{
	thread thred(print);
	if (thred.joinable())
	{
		cout << "主线程已经调用join函数" <<endl;
	} 
	else
	{
		cout << "主线程未调用join函数,进行调用" << endl;
		thred.join();
	}

	system("pause");
	return 0;
}



通过类和对象创建线程****↓**

#include <iostream>
#include <thread>
using namespace std;

class XX
{
public:
	//使用operator方法对()进行重载
	void operator()() 
	{
		cout << "类对象线程\t ID:" << this_thread::get_id() << endl;
	}
};

int main2()
{
	//直接使用类名调用需要再添加一层()否则报错
	thread thred1((XX()));
	thred1.join();
	
	//通过类对象调用
	XX xx;
	thread thred2((xx));
	thred2.join();

	system("pause");
	return 0;
}



Lambda表达式创建线程****↓**

#include <iostream>
#include <thread>
using namespace std;

int main3()
{
	// Lambda表达式[]()->{}
	thread thred1([]() {1 > 2 ? 1 : 2; });
	thred1.join();

	system("pause");
	return 0;
}



带参线程创建****↓**

#include <iostream>
#include <thread>
using namespace std;

void print4(int &number)
{
	number = 10086;
	cout << "number:" <<number <<endl;

}
int main4()
{
	int numb = 1000;

	//需要使用std::ref() 方法修饰参数
	thread thred1(print4,std::ref(numb));
	thred1.join();

	cout << "number:" << numb << endl;
	system("pause");
	return 0;
}



带智能指针的线程创建****↓**

#include <iostream>
#include <thread>
using namespace std;

void printf5( unique_ptr<int> ptr)
{
	cout << "&ptr:" << &ptr << endl;
	cout << "ptr:" << *ptr << endl;

}
int main5()
{
	unique_ptr<int> ptr(new int(1000));

	//指针只能使用move移动,但是需要注意移动后指针内存地址会被清空。
	thread thred1(printf5, move(ptr));
	thred1.join();

	system("pause");
	return 0;
}



通过类成员函数创建线程****↓**

#include <iostream>
#include <thread>
using namespace std;

class XXX
{
public:
	void pornt(int &number)
	{
		cout << "number:" << number << endl;
	}
};

int main()
{
	int numb = 10086;

	XXX xx;
	//类函数创建线程时需要添加一个参数为函数对象
	thread thred(&XXX::pornt,xx, std::ref(numb));
	thred.join();

	system("pause");
	return 0;
}

当多个线程对同一块内存空间进行访问时,如果线程都只读时是没关系的,但是如果这些线程对内存空间有修改那么需要添加互斥锁来保证在一个线程访问这片内存地址的同时不会被别的线程同时进行修改,从而造成内存泄漏。



版权声明:本文为weixin_45955823原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。