加入收藏 | 设为首页 | 会员中心 | 我要投稿 拼字网 - 核心网 (https://www.hexinwang.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 编程要点 > 语言 > 正文

C++多线程基本概念及 其创建线程的操作

发布时间:2022-12-10 11:23:20 所属栏目:语言 来源:
导读:  并发、进程、线程的基本概念

  并发两个或者多个任务(独立的活动)同时发生(进行):一个程序通知执行多个独立的任务并发假象(不是真正的并发):单核CPU通过上下文切换方式实现进程

  进程计算机中的

  并发、进程、线程的基本概念
 
  并发两个或者多个任务(独立的活动)同时发生(进行):一个程序通知执行多个独立的任务并发假象(不是真正的并发):单核CPU通过上下文切换方式实现进程
 
  进程计算机中的程序关于某数据集合上的一次运行活动
 
  进程特性
 
  动态性:进程是程序的一次执行过程,是临时的,有生命期,是动态产生,动态消亡的;
 
  并发性:任何进程都可以同其他进行一起并发执行;
 
  独立性:进程是系统进行资源分配和调度的一个独立单位;
 
  结构性:进程由程序,数据和进程控制块三部分组成
 
  线程每个进程都有一个主线程并且主线程是唯一的,也就是一个进程只能有一个主线程。vs编译器中ctr+f5编译运行程序时,实际是主线程调用mian函数中的代码。线程可以理解为代码执行通道,除了主线程之外,可以自己创建其他线程。
 
  并发实现方案
 
  主要解决是进程间通信问题
 
  同一电脑上可通过管道,文件,消息队列,共享内存等方式实现
 
  不同电脑可通过socket网络通信实现
 
  多个进程实现并发
 
  单独进程,多个线程实现并发 即一个主线程,多个子线程实现并发一个进程中的所有线程共享内存空间(共享内存),例如全局变量,指针引用等,所以多线程开销远远小于多进程。共享内存也会导致数据一致性问题(资源竞争问题)。
 
  C++线程编程基本操作
 
  1.首先需要包含thread头文件
 
  #include <thread>
 
  #include <iostream>
 
  2.创建线程: thread类创建一个线程
 
  #include <thread>
 
  void print()
 
  {
 
   std::cout<<"子线程"<<endl;     
 
  }
 
  int main()
 
  {
 
      //运行程序会调用abort函数终止程序     
 
      std::thread t1(print);    
 
      std::cout<<"主线程"<<std::endl;
 
  }
 
  3.join:加入/汇合线程。阻塞主线程,等待子线程执行结束,可理解为依附功能
 
  #include <thread>
 
  void print()
 
  {
 
   std::cout<<"子线程"<<endl;     
 
  }
 
  int main()
 
  {
 
      std::thread t1(print);    
 
      t1.join();      //阻塞主线程,等待子线程执行结束
 
      std::cout<<"主线程"<<std::endl;
 
      return 0;
 
  }
 
  4.detach:分离,剥离依附关系,驻留后台
 
  #include <thread>
 
  #include <iostream>
 
  #include <windows.h>
 
  void print()  
 
  {
 
   for (int i = 0; i < 10; i++)  
 
   {
 
    std::cout << "子线程"<<i << std::endl;
 
   }
 
  }
 
  int main()  
 
  {
 
   std::thread t1(print);
 
   std::cout << "主线程" << std::endl;
 
      //可用Sleep延时实现结果演示
 
   t1.detach();
 
   return 0;
 
  }
 
  注意:一旦detach线程后,便不可再使用join线程。
 
  5.joinable:判断当前线程是否可以join或deatch,如果可以返回true,不能返回false
 
  #include <thread>
 
  #include <iostream>
 
  void print()  
 
  {
 
   for (int i = 0; i < 10; i++)  
 
   {
 
    std::cout << "子线程"<<i << std::endl;
 
   }
 
  }
 
  int main()  
 
  {
 
   std::thread t1(print);
 
   t1.detach();
 
   if (t1.joinable())  
 
   {
 
    t1.join();
 
    std::cout << "可join" << std::endl;
 
   }
 
   std::cout << "主线程" << std::endl;
 
   return 0;
 
  }
 
  其他创建线程方法
 
  1.用类和对象
 
  #include <thread>
 
  #include <iostream>
 
  class Function  
 
  {
 
  public:
 
   void operator()()  
 
  {
 
    std::cout << "子线程" << std::endl;
 
   }
 
  };
 
  int main()  
 
  {
 
   Function object;
 
   std::thread t1(object);    //可调用对象即可
 
   t1.join();
 
   std::thread t2((Function()));
 
   t2.join();
 
   std::cout << "主线程" << std::endl;
 
   return 0;
 
  }
 
  2.Lambda表达式
 
  #include <thread>
 
  #include <iostream>
 
  int main()  
 
  {
 
  
 
  
 
   std::thread t1([] {std::cout << "子线程" << std::endl; });
 
   t1.join();
 
   std::cout << "主线程" << std::endl;
 
   return 0;
 
  }
 
  3.带引用参数创建方式
 
  #include <thread>
 
  #include <iostream>
 
  #include <thread>
 
  void printInfo(int& num)  
 
  {
 
   num = 1001;
 
   std::cout << "子进程:"<<num << std::endl;
 
  }
 
  int main()  
 
  {
 
   int num = 0;
 
   //std::ref 用于包装按引用传递的值。
 
   //std::cref 用于包装按const引用传递的值
 
   //error C2672: “invoke”: 未找到匹配的重载函数
 
   std::thread t(printInfo, std::ref(num));     
 
   t.join();
 
   std::cout << "主线程:"<<num << std::endl;
 
   return 0;
 
  }
 
  4.带智能指针参数创建方式
 
  #include <thread>
 
  #include <iostream>
 
  #include <thread>
 
  void printInfo(std::unique_ptr<int> ptr)  
 
  {
 
   std::cout << "子线程:"<<ptr.get() << std::endl;
 
  }
 
  int main()  
 
  {
 
   std::unique_ptr<int> ptr(new int(100));
 
   std::cout << "主线程:" << ptr.get() << std::endl;   
 
   std::thread t(printInfo,std::move(ptr));     
 
   t.join();
  
 

(编辑:拼字网 - 核心网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!