多线程 - 线程基本概念
大约 5 分钟
多线程 - 线程基本概念
参考:
- 【Bilibili】c++11并发与多线程视频课程(评价:啰嗦、全面但不深,乱糟糟的,最好配合点弹幕,特别是P5)(目前看到P10)
- 《Qt5开发及实例(第四版)》第12章,及配套ppt
- 《C++并发编程实战(中文版)》,pdf版,(英名《C++ Concurrency In Action》)
- 【CSDN】《探索C++多线程》:thread源码(一)(未看)
概念
并行、并发
并行
- 两个或更多的任务同时发生。这里可以在任务管理器中查看线程
并发
- 硬件并发
- 同时可以干多件事、提高性能
区别
- 并行不等于并发,并发是物理上的同时执行,并行是并发的子级
- 旧计算机只有单核cpu,由操作系统调度,每个时间片进行多次任务切换,这种上下文切换需要额外时间开销 只能实现并行,是并发的假象
- 现在是的cpu,多核指一个芯片上多个cpu(双核、4核、8核、16核) 这个可以在 “任务管理器 > 性能 > CPU > 右侧右键 > 将图形更改为 > 逻辑处理器” 中查看 能实现真正意义上的并发
程序、进程、线程
程序(可执行程序)
- windows下,扩展名为exe
- linux下,执行ls -la后显示rwx中的x表示执行权限
进程
- 进程是运行着的可执行程序
- 每个进程都会有一个PID
- 一个可执行程序运行起来了,就创建了一个进程。如果运行两次,则会创建两个进程
线程
- 主线程:每个进程都有且只有一个自动生成的主线程,主线程也是main函数所在线程
- 非主线程:除了主线程,可以通过代码来创建其他线程。线程是用来执行代码的
- 缺点:线程不是越多越好,每个线程都需要一个独立的堆栈空间(>1M)且切换需要额外时间开销,不建议超过200~300个
- 使用场景:可能阻塞或响应比较慢的代码、网络方面的操作(多线程/异步编程)
线程id(std::this_thread::get_id()
)
- 概念:每个线程都有一个不重复的线程id
- 使用:线程id可以通过
std::this_thread::get_id();
来获取 - 应用:调试时可以打印线程id来方便调试
进程与线程 查看与查询
查看方法
- 可以在 “任务管理器 > 性能 > CPU > 右侧进程与线程” 中查看进程数和线程数
- 可以在 “任务管理器 > 进程” 中查看具体进程,且会折叠一个应用中的多个进程
- 可以在 “任务管理器 > 用户” 中查看具体进程,但不会显示Winodws进程,且不会折叠一个应用中的多个进程
通过进程/线程查询
- 通过PID查找端口和协议
- CMD方法
netstat -ano
,列举程序PID和对应的网络端口netstat -ano | findstr 6636
,管道符筛选指定程序PID
- PID查找端口和协议:火绒剑方法
- 图形化界面更直观,也很容易用
并发的实现
两种实现方法
两种并发方法
- 多进程并发
- 进程之间通信(同一个电脑上:管道、文件、消息队列、共享内存。不同电脑上:socket通信技术)
- 多线程并发
- 有点类似于轻量级进程的感觉,但一个进程中所有线程共享地址空间(共享内存)
- 线程之间通信。全局变量、指针、引用等都可以在线程之间传递
- 所有使用多线程开销远远小于多进程
- 比较
- 建议优先使用多线程,开销小速度快
- 但要小心处理数据一致性问题,线程间的共享变量可能造成死锁的出现
多线程 vs 异步编程
博文很不错,推荐一看
共同点
- 异步和多线程两者都可以达到避免调用线程阻塞的目的,从而提高软件的可响应性
不同点
(1) 线程不是一个计算机硬件的功能,而是操作系统提供的一种逻辑功能,线程本质上是进程中一段并发运行的代码,所以线程需要操作系统投入CPU资源来运行和调度。
多线程优点:线程中的处理程序依然是顺序执行,符合普通人的思维习惯,所以编程简单。
多线程缺点:线程的使用(滥用)会给系统带来上下文切换的额外负担。并且线程间的共享变量可能造成死锁的出现
(2) 异步操作无须额外的线程负担,并且使用回调的方式进行处理
异步操作优点:在设计良好的情况下,处理函数可以不必使用共享变量(即使无法完全不用,最起码可以减少共享变量的数量),减少了死锁的可能
异步操作缺点:编写异步操作的复杂程度较高,程序主要使用回调方式进行处理,与普通人的思维方式有些 初入,而且难以调试。
总结
- 在实际设计时,我们可以将两者结合起来
- 异步特别适用于大多数IO密集型的应用程序
- 线程的适用范围则是那种需要长时间CPU运算的场合,例如耗时较长的图形处理和算法执行
C++11新标准线程库
以前版本
以往语言本身不支持,通过操作系统接口来实现,这些多线程代码不能跨平台,需要用一些库才能跨平台
winodws:
CreateThread();
_beginthread();
_beginthreadexe();
linux:
pthread_create();
C++11
C++11开始,提供了对多线程的支持,多线程代码能够跨平台实现