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

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

[[383623]]

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


前言

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

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

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

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

进程特性

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

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

并发实现方案

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

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

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

多个进程实现并发

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

C++线程编程基本操作

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

  1. #include <thread> 
  2. #include <iostream> 

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

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

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

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

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

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

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

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

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

其他创建线程方法

1.用类和对象

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

2.Lambda表达式

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

3.带引用参数创建方式

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

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

  1. #include <thread> 
  2. #include <iostream> 
  3. #include <thread> 
  4. void printInfo(std::unique_ptr<int> ptr)  
  5.  std::cout << "子线程:"<<ptr.get() << std::endl; 
  6. int main()  
  7.  std::unique_ptr<int> ptr(new int(100)); 
  8.  std::cout << "主线程:" << ptr.get() << std::endl;   
  9.  std::thread t(printInfo,std::move(ptr));     
  10.  t.join(); 
  11.  std::cout << "主线程:"<<ptr.get() << std::endl;  //主线程:00000000 move掉了 
  12.  return 0; 

5.类的成员函数

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

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

 

责任编辑:姜华 来源: 今日头条
相关推荐

2021-03-05 07:38:52

C++线程编程开发技术

2012-05-18 10:36:20

CC++编程

2021-12-14 08:28:08

Java多线程线程

2023-06-06 08:17:52

多线程编程Thread类

2021-12-26 18:22:30

Java线程多线程

2013-06-07 16:30:08

iOS多线程iOS开发NSThread

2013-07-16 13:39:11

2010-02-05 15:30:54

C++多线程测试

2010-02-04 10:19:39

C++多线程

2010-01-18 14:09:58

C++多线程

2024-02-02 18:29:54

C++线程编程

2009-03-12 10:52:43

Java线程多线程

2010-01-21 11:25:44

linux多线程线程资源

2013-07-16 10:12:14

iOS多线程多线程概念多线程入门

2023-06-16 08:36:25

多线程编程数据竞争

2021-12-28 09:10:55

Java线程状态

2009-06-17 11:23:00

Java多线程

2023-06-13 13:39:00

多线程异步编程

2011-06-22 16:08:40

Qt 多线程 事件循环

2024-06-24 08:10:00

C++互斥锁
点赞
收藏

51CTO技术栈公众号