多线程与多进程 线程安全
多核多线程多进程
任务调度
操作系统一般都会采用时间片轮转的抢占式调度
image进程
操作系统是计算机的管理者,它负责任务的调度、资源的分配和管理,统领整个计算机硬件。进程是操作系统分配资源的最小单位。进程是一个程序的一次动态执行过程。进程由程序、数据和进程控制块组成。其中进程控制块包含进程的描述信息和控制信息,是进程存在的唯一标志。
进程的特征:
- 动态性: 进程只是程序的一次执行过程,是临时的,有生命周期的。动态产生,动态消亡
- 并发性: 任何进程都可以和其他进程一起并发执行
- 独立性: 进程是操作系统和进行资源分配和调度的一个独立单位
- 结构性: 进程由程序 数据 进程控制块组成
线程
早期的计算器系统没有线程的概念,只有进程。这时,进程是资源分配的最小单位,也是程序执行的最小单位,每个进程之间独立,每个进程拥有自己独立的内存
随着计算机的发展,进程之间切换开销大的弊端不断凸显,无法满足越来越复杂的程序,于是出现了线程,线程变成了程序执行的最小单元。一个进程可以有一个或者多个线程,各个线程之间共享程序的内存空间(进程所在的内存空间)。线程由线程ID,当前指令指针(PC)、寄存器和堆栈组成
进程和线程的关系
- 线程是程序执行的最小单位,进程是操作系统资源分配的最小单位
- 一个进程由一个或者多个线程组成,线程是一个进程中代码的不同执行路线
- 进程之间相互独立名,但是一个进程下的多个线程共享内存空间
- 调度和切换:线程之间的切换速度比进程之间的切换要快很多
一个进程包括多个线程示意图
image相比于单线程 多线程实际上就是时间片轮转 实现并发
image总之,线程和进程都是一种抽象的概念,线程是一种比进程更小的抽象,线程和进程都可用于实现并发。
每个进程中的内容 | 每个线程中的内容 |
---|---|
地址空间 | 程序计数器 |
全局变量 | 寄存器 |
打开文件 | 堆栈 |
子进程 | 状态 |
即将发生的报警 | |
信号与信号处理程序 | |
账户信号 | |
同步、互斥信号量 |
多核和多线程
多核(心)处理器是指在一个处理器上集成多个运算核心从而提高计算能力,也就是有多个真正并行计算的处理核心,每一个处理核心对应一个内核线程。程序一般不会直接去使用内核线程,而是去使用内核线程的一种高级接口——轻量级进程(Light Weight Process,LWP),轻量级进程就是我们通常意义上所讲的线程(我们在这称它为用户线程)
用户线程与内核线程的对应关系有三种模型:一对一模型、多对一模型、多对多模型,在这以4个内核线程、3个用户线程为例对三种模型进行说明。
一对一模型
优点:
- 真并行 不堵塞
缺点:
- 程序并行数量收到内核线程的限制
- 用户线程切换开销大
多对一模型
优点
- 用户线程切换速度快
缺点:
- 某个用户线程堵塞,会导致内核线程堵塞
多对多模型
优点
- 一个用户线程阻塞不会导致所有线程阻塞
- 用户线程数量没有限制
线程安全
线程不安全:多个线程同时访问一个数据,并且对数据做不同的改变,这个时候数据乱了,也就是线程不安全
如何保证线程安全?限制多个线程访问一个数据时,一次只允许一个线程访问该数据,只有这个线程对该数据访问结束之后,其他线程才能访问该数据。同步(synchronization) 同步最常见的方式就是使用锁(Lock),也称为线程锁。锁是一种非强制机制,每一个线程在访问数据或资源之前,首先试图获取(Acquire)锁,并在访问结束之后释放(Release)锁。在锁被占用时试图获取锁,线程会进入等待状态,直到锁被释放再次变为可用。
一个生动的例子:
假设你在工行有一个银行账户,两张银联卡(自己手里一张,女朋友手里一张),里面有100万。假设取钱就两个过程:1.检查账户余额,2.取出现金(如果要取出的金额 > 账户余额,则取现成功,否则取现失败)。有一天你要买房想把钱取出来,而此时你女朋友也想买一辆车(假设你们事先没有商量)。两个人都在取钱,你在A号ATM机取100万,女朋友在B号ATM机取80万。这时A号ATM检查账户余额发现有100万,可以取出;而与此同时,同一时刻B号ATM也在检查账户余额发现有100万,可以取出;这样,A、B都把钱取出来了
几个问题
-
单核cpu能实现多进程吗?
可以。操作系统会使用时间片轮转的方法实现并发,实现多任务,实现多进程
image这张图是我的电脑的资源管理器截图,可以看到我的cpu是四核八线程,我的进程数200+,线程数2500+
参考:
https://blog.csdn.net/luoweifu/article/details/46701167