C++多线程编程之创建线程篇

 多线程是程序员必须掌握的一门技术,本文主要是针对于C++新标准中多线程库,需要具备一定C++基础方可学习。

10余年的乌拉特后网站建设经验,针对设计、前端、开发、售后、文案、推广等六对一服务,响应快,48小时及时工作处理。网络营销推广的优势是能够根据用户设备显示端的尺寸不同,自动调整乌拉特后建站的显示方式,使网站能够适用不同显示终端,在浏览器中调整网站的宽度,无论在任何一种浏览器上浏览网站,都能展现优雅布局与设计,从而大程度地提升浏览体验。创新互联从事“乌拉特后网站设计”,“乌拉特后网站推广”以来,每个客户项目都认真落实执行。

前言

本章节主要C++多线程编程中的一些基本概念以及几种创建线程的方式。

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

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

进程计算机中的程序关于某数据集合上的一次运行活动

进程特性

  1. 动态性:进程是程序的一次执行过程,是临时的,有生命期,是动态产生,动态消亡的;
  2. 并发性:任何进程都可以同其他进行一起并发执行;
  3. 独立性:进程是系统进行资源分配和调度的一个独立单位;
  4. 结构性:进程由程序,数据和进程控制块三部分组成

线程每个进程都有一个主线程并且主线程是唯一的,也就是一个进程只能有一个主线程。vs编译器中ctr+f5编译运行程序时,实际是主线程调用mian函数中的代码。线程可以理解为代码执行通道,除了主线程之外,可以自己创建其他线程。

并发实现方案

主要解决是进程间通信问题

同一电脑上可通过管道,文件,消息队列,共享内存等方式实现

不同电脑可通过socket网络通信实现

多个进程实现并发

单独进程,多个线程实现并发 即一个主线程,多个子线程实现并发一个进程中的所有线程共享内存空间(共享内存),例如全局变量,指针引用等,所以多线程开销远远小于多进程。共享内存也会导致数据一致性问题(资源竞争问题)。

C++线程编程基本操作

1.首先需要包含thread头文件

 
 
 
 
  1. #include 
  2. #include 

2.创建线程: thread类创建一个线程

 
 
 
 
  1. #include 
  2. void print()
  3. {
  4.  std::cout<<"子线程"<
  5. }
  6. int main()
  7. {
  8.     //运行程序会调用abort函数终止程序    
  9.     std::thread t1(print);   
  10.     std::cout<<"主线程"<
  11. }

 3.join:加入/汇合线程。阻塞主线程,等待子线程执行结束,可理解为依附功能

 
 
 
 
  1. #include 
  2. void print()
  3. {
  4.  std::cout<<"子线程"<
  5. }
  6. int main()
  7. {
  8.     std::thread t1(print);   
  9.     t1.join();      //阻塞主线程,等待子线程执行结束
  10.     std::cout<<"主线程"<
  11.     return 0;
  12. }

 4.detach:分离,剥离依附关系,驻留后台

 
 
 
 
  1. #include 
  2. #include 
  3. #include 
  4. void print() 
  5. {
  6.  for (int i = 0; i < 10; i++) 
  7.  {
  8.   std::cout << "子线程"<
  9.  }
  10. }
  11. int main() 
  12. {
  13.  std::thread t1(print);
  14.  std::cout << "主线程" << std::endl;
  15.     //可用Sleep延时实现结果演示
  16.  t1.detach();
  17.  return 0;
  18. }

注意:一旦detach线程后,便不可再使用join线程。

5.joinable:判断当前线程是否可以join或deatch,如果可以返回true,不能返回false

 
 
 
 
  1. #include 
  2. #include 
  3. void print() 
  4. {
  5.  for (int i = 0; i < 10; i++) 
  6.  {
  7.   std::cout << "子线程"<
  8.  }
  9. }
  10. int main() 
  11. {
  12.  std::thread t1(print);
  13.  t1.detach();
  14.  if (t1.joinable()) 
  15.  {
  16.   t1.join();
  17.   std::cout << "可join" << std::endl;
  18.  }
  19.  std::cout << "主线程" << std::endl;
  20.  return 0;
  21. }

其他创建线程方法

1.用类和对象

 
 
 
 
  1. #include 
  2. #include 
  3. class Function 
  4. {
  5. public:
  6.  void operator()() 
  7. {
  8.   std::cout << "子线程" << std::endl;
  9.  }
  10. };
  11. int main() 
  12. {
  13.  Function object;
  14.  std::thread t1(object);    //可调用对象即可
  15.  t1.join();
  16.  std::thread t2((Function()));
  17.  t2.join();
  18.  std::cout << "主线程" << std::endl;
  19.  return 0;
  20. }

2.Lambda表达式

 
 
 
 
  1. #include 
  2. #include 
  3. int main() 
  4. {
  5.  std::thread t1([] {std::cout << "子线程" << std::endl; });
  6.  t1.join();
  7.  std::cout << "主线程" << std::endl;
  8.  return 0;
  9. }

3.带引用参数创建方式

 
 
 
 
  1. #include 
  2. #include 
  3. #include 
  4. void printInfo(int& num) 
  5. {
  6.  num = 1001;
  7.  std::cout << "子进程:"<
  8. }
  9. int main() 
  10. {
  11.  int num = 0;
  12.  //std::ref 用于包装按引用传递的值。
  13.  //std::cref 用于包装按const引用传递的值
  14.  //error C2672: “invoke”: 未找到匹配的重载函数
  15.  std::thread t(printInfo, std::ref(num));    
  16.  t.join();
  17.  std::cout << "主线程:"<
  18.  return 0;
  19. }

4.带智能指针参数创建方式

 
 
 
 
  1. #include 
  2. #include 
  3. #include 
  4. void printInfo(std::unique_ptr ptr) 
  5. {
  6.  std::cout << "子线程:"<
  7. }
  8. int main() 
  9. {
  10.  std::unique_ptr ptr(new int(100));
  11.  std::cout << "主线程:" << ptr.get() << std::endl;  
  12.  std::thread t(printInfo,std::move(ptr));    
  13.  t.join();
  14.  std::cout << "主线程:"<
  15.  return 0;
  16. }

5.类的成员函数

 
 
 
 
  1. #include 
  2. #include 
  3. #include 
  4. class MM 
  5. {
  6. public:
  7.  void print(int& num) 
  8. {
  9.   num = 1001;
  10.   std::cout << "子线程:"<
  11.  }
  12. };
  13. int main() 
  14. {
  15.  MM mm;
  16.  int num = 10;
  17.  std::thread t(&MM::print,mm,std::ref(num));    
  18.  t.join();
  19.  std::cout << "主线程:"<< num << std::endl;
  20.  return 0;
  21. }

好了,创建线程就介绍到这里,大家可以先练习一下,下章节讲解共享数据访问。

当前文章:C++多线程编程之创建线程篇
文章来源:http://www.gawzjz.com/qtweb/news17/175717.html

网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联