C++之多线程编程

一、并发的实现

        1.多进程并发主要解决进程间通信的问题

                ①同一电脑上:管道、文件、消息队列、内存共享。

                ②不同电脑上:socket网络通信。

        2. 单进程中的多个线程并发(一个主线程+多个子线程实现并发)

                ①一个进程中的所有线程共享内存空间 eg:全局变量,指针引用

二、线程的多种创建方式

 1. 调用thread类去创建线程对象

        头文件和子线程处理函数(以下所有代码段共用):

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

//线程处理函数
void print() {
	Sleep(3000);
	cout << "子线程运行喽........" << endl;
}

                注:如果创建一个线程而不做处理,会调用abort函数中止程序

                        一个线程只能join一次,否则也会abort。

        1.1. 使用join()函数加入,汇合线程,阻塞主线程,等待子进程执行结束,才会回到主线程

int main(){
	//创建线程
	thread test1(print);
	test1.join();        //阻塞(若test1线程未执行完,则主线程不会打印)
	cout << "主线程运行喽........." << endl;
}

运行说明:三秒后依次打印出

 

1.2. 使用detach()函数,打破依赖关系,把子线程驻留后台

        注:线程detach后,就不能在join了 

int main(){
	//创建线程
	thread test1(print);
	test1.detach();
	cout << "主线程运行喽........." << endl;
}

运行说明:直接只打印出:

 

1.3 使用joinable()函数判断当前线程是否可以做join或者detach操作,若可以,返回true。

int main(){
	//创建线程
	thread test1(print);
	test1.detach();
	cout << "主线程运行喽........." << endl;
	if (test1.joinable())
		test1.join();
	else
		cout << "该子线程已经被处理啦....." << endl;
}

运行说明:

 

2.  通过类和对象创建线程

class Li {
public:

	//STL仿函数
	void operator()() {
		cout << "子线程启动喽....." << endl;
	}
};
int main(){
	//正常写法:对象充当线程处理函数
	Li li;
	thread test1(li);
	test1.join();

	Li(); //无名对象
	thread test2((Li()));   //这里如果不多写一个括号,编译器就会把test2解析成一个函数,Li()解析成一个参数,从而出错
	test2.join();
	
}

运行:

 

3. 带参的方式创建线程

//传引用可以改变num的实际值
void printInfo(int& num) {
	cout << "子线程运行喽...." << endl;
}
int main(){
	int num = 0;
	//ref 用于包装 “引用传递值” 
	thread test1(printInfo, ref(num));
	test1.join();
	cout << "我是主线程...." << endl;
	
}

运行:

4. Lambda表达式创建线程

int Max(int a, int b) {
	return a > b ? a : b;
}
int main(){
	int (*pMax)(int, int) = nullptr;
	pMax = [](int a, int b)->int {return a > b ? a : b; };
	[] {cout << "helloword" << endl; }();
	cout << pMax(3, 5) << endl;
	thread test1([] {cout << "我是子线程..." << endl; });
	test1.join();
	cout << "我是主线程..." << endl;
	return 0;
}

运行:

 

5. 以智能指针为参数创建线程

void print(unique_ptr<int> ptr) {
	cout << "我是子线程:" << ptr.get()<<endl;
}
int main(){
	int* p = new int(100);
	unique_ptr<int> ptr(p);
	cout << "我是主线程:" << ptr.get() << endl;
	thread test1(print, move(ptr)); //move移动语义,通俗的说就是把ptr移动到子线程中了,这样的话,主线程中的ptr就没了    
	test1.join();
	cout << "我是主线程:" << ptr.get()<<endl;
	
}

运行:

 

6. 以类的成员函数充当线程处理函数来创建线程

class Li {
public:
	void print(int& num) {
		num = 1001;
		cout << "我是子线程:" << this_thread::get_id() << endl;
	}
};
int main(){
	Li li;
	int num = 1007;
	//需要说明 是哪个对象
	thread test1(&Li::print,li,ref(num));
	test1.join();
	cout << "我是主线程:" << this_thread::get_id()<<endl;
	
}

运行:

 

  • 12
    点赞
  • 85
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值