文章目录
- 一、并发、进程、线程
- 1. 并发、进程的基本概念和综述
- (1)并发
- (2)可执行程序
- (3)进程
- (4)线程
- 2. 并发的实现方法
- (1)多进程并发
- (2)多线程并发
- (3)总结
- 3. C++11新标准线程库
一、并发、进程、线程
1. 并发、进程的基本概念和综述
(1)并发
- 什么是并发
- 两个或者更多的任务(独立的活动)同时发生(执行)
- 上下文切换
- 定义:过去的计算机,只有一个CPU,同一时刻只能执行一个任务,并发的实现要靠操作系统调查CPU,每秒中进行多次 “任务切换”,这就是上下文切换
- 进行上下文切换是有时间开销的(切换时涉及保存环境信息和恢复环境信息)
- 利用上下文切换,可以实现一种并发的假象,不是真正的并发
- 硬件并发
- 随着硬件的发展,出现多核CPU,这时就能让不同的核心执行不同的任务,实现真正的并发
- 使用并发的原因
- 同时执行多个任务,提高性能
(2)可执行程序
- 定义:磁盘上的一个文件,window下是
.exe
文件
(3)进程
- 定义
- 进程就是程序的运行
- 一个可执行程序运行起来,就可以看作创建了一个进程
(4)线程
- 主线程
- 每个进程都有一个主线程,这个主线程是唯一的,一个进程中有且只有一个主线程
- 产生一个进程后,主线程就随着这个进程的创建自动启动起来
- 运行一段程序的时候,本质上是进程的主线程来执行(调用)这个
main
函数中的代码 - 主线程和进程同生同灭
- 线程
- 用来执行代码的
- 可以理解成一条代码的执行通路,程序运行时,主线程的通路是从
main
开始到return
结束 - 除了主线程之外,可以通过代码创建其他线程(子线程),他们可以走不同于主线程的其他通路
- 每创建一个新线程,就可在同一个时刻多执行一个任务
- 多线程(并发)
- 线程不是越多越好,都需要一个独立的堆栈空间(1M左右)
- 线程之间的切换是有开销的,线程太多,切换太频繁,反而会降低效率
- 例子
- 游戏服务器,给每个玩家开一个线程,比如
- 玩家一线程处理充值
- 玩家二线程处理抽卡
- 玩家三线程处理…
- …
- 小结
- 线程是用来执行代码的
- 把线程理解为一条代码的执行通路(道路),一个线程代表一个新的通路
- 一个进程自动包含一个主线程,主线程随着进程默默启动并运算,我们可以通过编码来创建多个其他线程(非主线程),但是创建的数量不宜太多
- 因为主线程是自动启动的,所以一个进程中至少有一个线程(主线程)
- 说白了,多线程程序就是可以同时干多个事情,运行效率高
2. 并发的实现方法
- 并发
- 两个或者更多的任务(独立的活动)同时发生(执行)
(1)多进程并发
- 创建多个进程,每个进程一个主线程,靠多个主线程实现并发
- 每运行一个可执行程序,就多一个并发进程
- 进程间可以相互通信
- 同一个电脑上的进程间通信
- 管道
- 文件
- 消息队列
- 共享内存
- 不同电脑上的进程间通信
- socket
(2)多线程并发
- 在单一进程里创建多个线程来实现并发(自己写代码创建除了主线程外的其他线程)
- 每个线程都有自己的运行路径
- 一个进程中的所有线程共享内存
- 全局变量、指针、引用都能在线程之间传递
- 好处:线程间共享内存的特点使得线程间通信非常方便,开销小,因此多线程开销远远小于多进程
- 坏处:数据一致性问题,比如两个线程要操作同一块内存空间,可能互相影响(如读者-写者问题)
- 需要并发时,优先考虑多线程技术
(3)总结
- 和进程比,线程有如下优点
- 线程启动更快,更轻量级
- 系统资源开销更小,执行速度更快(比如共享内存实现了线程间快速通信)
- 和进程比,线程有如下缺点
- 使用有一定困难,要小心处理数据一致性问题
3. C++11新标准线程库
- 以往的C++多线程要使用操作系统提供的多线程接口,函数不同不能跨平台;要实现跨平台得配置库,麻烦
- 从C++11开始,C++语言本身提供了多线程支持,实现了C++多线程程序的跨平台