多线程的创建

线程的多种创建方式
C++线程创建的过程 – 普通函数的方式:
2.1 包含头文件 #include
2.2 创建线程:调用thread 类去创建一个线程对象
注意点:创建一个线程,不做处理,会调用abort函数终止程序
2.3 join函数 加入、汇合线程到主线程,阻塞主线程;等待子线程执行结束,
才会回到主线程
注意:一个线程只能join()一次,join()多次会引发中断
2.4 detach(); 函数分离,打破依赖关系;把子线程驻留后台。 注意与join()的区别;
当线程detach()后,就不能再join()了。
2.5 joinable()判断当前线程是否可以做join或者detach过程,可以返回true,否则false

其他创建线程的方法:
1、普通函数的方式,上面介绍过了
2、通过类和对象创建线程
3、Lambda表达式创建线程
4、带参的方式创建线程
5、带智能指针的方式创建线程
通过类的的成员函数创建进程

普通函数的方式

#include<iostream>
#include<thread>
#include<windows.h>
using namespace std;

//线程处理函数
void print(){
Sleep(5000);  //让子线程休眠5000毫秒= 5秒钟
cout<<”子线程运行...<<endl;
}
//创建第二个子线程
void print2() {
	Sleep(5000);  //此时子线程2也会休眠5秒
	cout << "子线程2运行..." << endl;
}

int main(){
//创建线程
thread t1(print);
thread t2(print2);  //创建子线程2
	t1.join();  //阻塞;也就是说子线程没有运行结束,主线程是不会打印的
	t2.join();
	/*
此时程序一共休眠5S
		output: 子线程1运行...  子线程2运行...
		        主线程运行...
	*/
t1.join();   //阻塞; 也就是说子线程没有打印完,主线程是不会打印的

cout<<”主线程运行...<<endl;
return 0;
}

以类的成员构造线程


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

class MM {
public:
	void print(int& num) {
		num = 10001;
		cout << "子线程..." << this_thread::get_id() << endl;
	}
};

int main() {

	MM mm;
	int num = 1001;
	//需要告诉 是哪个对象
	thread t1(&MM::print,mm,ref(num));
	t1.join();

	cout << "主线程..." << this_thread::get_id() << endl;

	system("pause");
	return 0;
}

以智能指针为参数创建

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

/*
	以智能指针为参数的线程处理函数
*/

void print(unique_ptr<int> ptr) {
	cout << "子线程:" << ptr.get() << endl;  //输出智能指针的地址
	cout << this_thread::get_id() << endl;//获取线程id
}

int main() {
	unique_ptr<int> ptr(new int(1000));
	cout << "主线程..." << ptr.get() << endl;  //使用ptr.get()获取; 此时输出的是智能指针的地址
	
	thread t1(print,move(ptr)); //注意:此时需要用move
	t1.join();  //调用子线程;输出智能指针的地址;此时和上面主线程输出的结果是一样的

	cout << "主线程..." << ptr.get() << endl;  //此时输出00000000 ;因为move的原因
	cout << this_thread::get_id() << endl;//获取线程id

	system("pause");
	return 0;

}

带参的方式创建

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

/*
	带参引用创建线程
*/


void printInfo(int& num) {
	num++;
	cout << "子线程\t" << num << endl;
}

int main() {

	int num = 0;
	//std::ref 用于包装引用传递值
	thread t1(printInfo,std::ref(num));
	t1.join(); // 将子线程加入到主线程

	cout << "主线程..." << num << endl;

	system("pause");
	return 0;
}

多线程数据同步问题


#include<iostream>
#include<thread>
#include<mutex>
#include<list>  //作为共享内存
using namespace std;

mutex mtx;  //设置互斥量

class SeaKing{
public:
	
	void makeFriend(list<int> &mm) {
		lock_guard<std::mutex> mtx_locker(mtx);  //mtx_locker(mtx)用于自动锁定解锁
		for (int i = 0; i < 10; i++) {
			mm.push_back(i);
			cout << "增加一位女朋友:" << i << endl;
			
		}
	}

	void breakUp(list<int> &mm) {
		lock_guard<std::mutex> mtx_locker(mtx);
		for (int j = 0; j < 10;j++) {
			if (!mm.empty()) {
				mm.pop_front();
				cout << "分手一位女朋友:" << mm.front() << endl;
				
			}
			else {
				cout << "都分手了" << endl;
			}
		}
	}

protected:
	list<int> mm;
};

int main() {
	list<int> mm;
	SeaKing fx;
	thread t1(&SeaKing::makeFriend,fx,ref(mm));
	thread t2(&SeaKing::breakUp,fx,ref(mm));
	t1.join();
	t2.join();

	system("pause");
	return 0;
}

利用互斥量解决并发问题

#include<iostream>
#include<thread>
#include<windows.h>
#include<mutex>
using namespace std;

/*
实现创建多线程
*/
void Fun_1();          //声明分支线程函数Fun_1()
void Fun_2();          //声明分支线程函数Fun_2()

unsigned int counter = 0;      //定义变量counter,通过变量counter的变化来观察线程同步情况
std::mutex mtx;           //定义mutex类的对象mtx构造互斥元,互斥占有一个变量,一段时间内仅一个线程可以访问

int main()
{
	std::thread thrd_1(Fun_1);     //创建线程thrd_1,thrd_1调用函数Fun_1
	std::thread thrd_2(Fun_2);     //创建线程thrd_2,thrd_2调用函数Fun_2
	thrd_1.join();        //join()函数启动子线程而阻塞主线程,子线程会按照开启的先后顺序同步运行,
						 //当子线程运行结束后,才会继续运行主线程
	thrd_2.join();        //启动线程thrd_2,并且阻塞主线程,等到线程thrd_2运行结束后,再继续运行主线程;
	cout << "counter= " << counter << endl;
	system("pause");
	return 0;
}

void Fun_1()
{
	while (true)
	{
		/*std::lock_guard类模板,用于自动锁定解锁,直到对象作用域结束。在 lock_guard 对象构造时,
		传入的mutex对象 mtx 会被当前线程锁住。在lock_guard 对象被析构时,它所管理的mutex对象mtx会自动解锁*/
		std::lock_guard<std::mutex> mtx_locker(mtx);
		counter++;
		if (counter < 5)
			cout << "Function 1 counting !  counter=" << counter << endl;
		else
			break;
	}
}

void Fun_2()
{
	while (true)
	{
		/*std::lock_guard类模板,用于自动锁定解锁,直到对象作用域结束。在 lock_guard 对象构造时,
		传入的mutex对象 mtx 会被当前线程锁住。在lock_guard 对象被析构时,它所管理的mutex对象mtx会自动解锁*/
		std::lock_guard<std::mutex> mtx_locker(mtx);
		counter++;
		if (counter < 5)
			cout << "Function 2 counting !  counter=" << counter << endl;
		else
			break;
	}
}

std::lock_guard类模板,用于自动锁定解锁,直到对象作用域结束。在 lock_guard 对象构造时,传入的mutex对象 mtx 会被当前线程锁住。在lock_guard 对象被析构时,它所管理的mutex对象mtx会自动解锁;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值