C++6种基础线程的应用

1 线程基础

1.1 并发、进程、线程的基本概念

  • 并发:两个或者多个独立的活动同时进行,并发假象:单核CPU,上下文切换
  • 进程:计算机调动计算机资源的最小单位,关于某一个数据集合上的一次运行活动
  • 线程:线程是调度CPU的最小单元。也叫轻量级进程,在一个进程里可以创建多个线程,每个线程都拥有各自的计数器、堆栈和局部变量等属性,并且能够访问共享的内存变量。

并发的实现:

  1. 多进程实现并发
    • 主要解决的问题进程间通信的问题
    • 一个电脑上:管道,文件,消息队列,内存共享
    • 不同电脑通过SOCKET网络通信实现
  2. 单个进程,多线程实现并发
    • 一个进程中的所有线程共享的内存空间,例如:全局变量,指针引用

1.2 线程的多种创建方式

1.2.1 普通函数创建

包含头文件

创建线程

  • 创建一个线程,不做处理,会调用abort函数终止程序
  • 一个线程只能join一次

join()函数加入,回合线程,阻塞主线程,等待子线程执行结束,才会回到主线中

detach()函数,分离,打破依赖关系,子线程执没执行完,我也不知道

joinable()判断当前线程是否可以做join或者detach过程,可以返回true,不可以返回false

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

void print(){
    Sleep(5000);
    cout << "子线程运行..." << endl;
}
int main(){
    //创建线程
    thread test1(print);
    test1.join();     //阻塞,等待子线程结束后,才向下运行
    cout << "主线程。。。。" << endl;
    if(test1.joinable()){
        test1.join();
        cout<<"可以"<<endl;
    }else {
        cout <<"子线程已经被处理"<<endl;
    }
    
    return 0;
}
1.2.2通过类和对象
#include <iostream>
#include <thread>
using namespace std;

class MM
{
public:
	//类似仿函数,用类名模仿函数的行为
	void operator()() {
		cout << "子线程启动..." << endl;
	}
};

int main() {

	MM mm;
	thread test1(mm);
	test1.join();
	thread test2((MM()));
	test2.join();

	cout << "主线程结束" << endl;

	return 0;
}
1.2.3 Lambda表达式创建线程
#include <iostream>
#include <thread>
using namespace std;

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; };

	thread test1([] { cout << "子线程启动..." << endl; });

	test1.join();
	cout << "主线程结束" << endl;

	return 0;
}
1.2.4 带参的方式创建线程
#include <iostream>
#include <thread>
using namespace std;

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

int main() {

	//std::ref 用于包装引用传递的值
	int num = 1;
	thread test1(printInfo, std::ref(num));
	test1.join();
	cout << "主线程结束" << endl;

	return 0;
}
1.2.5 带智能指针创建线程
#include <iostream>
#include <thread>
using namespace std;

void printInfo(unique_ptr<int> ptr) {
	cout << "子线程\t" << ptr.get() << "\t";
	cout << this_thread::get_id() << endl;
}

int main() {

	//std::ref 用于包装引用传递的值 
	unique_ptr<int> ptr(new int(1000));   //好处就是不需要手动的释放

	//move 移动语义
	thread test1(printInfo, move(ptr));
	test1.join();
	cout << "主线程结束\t" << ptr.get() << "\t";
	cout << this_thread::get_id() << endl;
	// 这里数据移动到了子线程,主线程就不在

	cout << "*******************************************" << endl;


	return 0;
}
1.2.6 通过类的成员函数创建线程
#include <iostream>
#include <thread>
using namespace std;

class MM {

public:
	void print(int & num) {
		num = 1001;
		cout <<"子线程\t"<< this_thread::get_id() << endl;
	}

};

int main() {

	MM mm;
	int num = 1007;

	thread test1(&MM::print,mm, ref(num));
	test1.join();
	cout << "主线程结束\t"  << "\t";
	cout << this_thread::get_id() << endl;
	// 这里数据移动到了子线程,主线程就不在

	cout << "*******************************************" << endl;


	return 0;
}
1.2.7 线程访问共享数据出现的冲突

多个线程共享数据的时候,出现冲突,这里就需要线程锁


基础就到这里了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值