• 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
    #include
    #include
    using namespace std;
    
    void print(){
        Sleep(5000);
        cout << "子线程运行..." << endl;
    }
    int main(){
        //创建线程
        thread test1(print);
        test1.join();     //阻塞,等待子线程结束后,才向下运行
        cout << "主线程。。。。" << endl;
        if(test1.joinable()){
            test1.join();
            cout<<"可以"<
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    1.2.2通过类和对象
    #include 
    #include 
    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
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    1.2.3 Lambda表达式创建线程
    #include 
    #include 
    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
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    1.2.4 带参的方式创建线程
    #include 
    #include 
    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
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    1.2.5 带智能指针创建线程
    #include 
    #include 
    using namespace std;
    
    void printInfo(unique_ptr ptr) {
    	cout << "子线程\t" << ptr.get() << "\t";
    	cout << this_thread::get_id() << endl;
    }
    
    int main() {
    
    	//std::ref 用于包装引用传递的值 
    	unique_ptr 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
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    1.2.6 通过类的成员函数创建线程
    #include 
    #include 
    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
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    1.2.7 线程访问共享数据出现的冲突

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


    基础就到这里了

  • 相关阅读:
    【JavaScript】DOM的其他查询
    2023Fall美高选校必看!敏思跃动独家发布美国私立寄宿高中选校分级表
    XFF漏洞利用([SWPUCTF 2021 新赛]Do_you_know_http)
    Java修仙传之神奇的ES(基础使用)
    JavaScript入门
    JVM 垃圾回收
    [每周一更]-(第72期):Docker容器瘦身方式
    Maven项目管理工具
    C++图的建立---邻接矩阵-----邻接表
    Java项目:57 ssm011线上旅行信息管理系统ssm+vue
  • 原文地址:https://blog.csdn.net/suren_jun/article/details/127377541