进程与线程
前言:进程和线程是计算机操作系统中非常重要的内容,也是计算机专业就业面试过程中必问的题目,笔试中必考的题目,今天花一点时间整理下,本身自己也学的不太精,现在整理一下思路,并且用代码实现,进一步理解他的原理。
进程是操作系统提供的一种抽象,即使cpu只有一个,他们也支持(伪)并发操作的能力。他们将单个的cpu变换成多个虚拟的cpu。
进程的定义并没有标准的说法:
关于进程的概念,除了“正在执行的程序”这一点,我觉得还有两点要加以强调。
1, 进程是为描述并行发展出来的一种模型。
2, 进程是一种抽象概念。
笼统的说,进程是正在执行的程序。在较高的层次上,进程是一个抽象概念,是描述并行的一种模型。在较低的层次上,包括进程映像的结构、执行的细节和在进程间切换处理机的方法。
在进程模型中,计算机上所有可运行的软件,通常也包括操作系统,被组织成若干顺序进程,简称进程。一个进程就是一个正在执行的程序的实例,包括程序计数器、寄存器和变量的当前值,每个进程都拥有自己虚拟的cpu。
进程和程序的区别:进程是某种类型的一个活动,它有程序、输入、输出以及状态。程序就是一段可以执行的代码,像磁盘上的exe、dll等,程序是死的,进程是活的。如果把进程比作是一个菜谱,进程就是按照菜谱做菜的整个过程。
有4中主要事件导致进程的创建:
1.系统初始化
2.执行了正在运行的进程所调用的进程创建系统调用。
3.用户请求创建一个新进程。
4.一个批处理作业的初始化。
进程的终止:
1.正常退出(自愿的)
2.出错退出(自愿的)
3.严重错误(非自愿的)
4.被其他进程杀死(非自愿的)
进程的状态:
1.运行态
2.就绪态
3.阻塞态
![](https://app.yinxiang.com/shard/s33/res/94bd4fad-7787-42d9-9fbf-7eed88daa070.png?resizeSmall&width=572)
为了实现进程模型,操作系统维护着一种进程表,每个进程都占用一个进程表项。
![](https://app.yinxiang.com/shard/s33/res/3033dc48-679d-487e-9d6e-58938707442e.png?resizeSmall&width=572)
进程是对运行中的程序的一个抽象,有了这个抽象才能使多个程序在内存中并发的运行。多道程序设计可以提高cpu的利用率。
线程
线程是进程的执行单元,在传统操作系统中,每个进程有一个地址空间和一个控制线程。
线程的优点:1.同一个进程中可以并行的运行多个顺序线程
2.线程是轻量级的,上下文切换快。
3.提高了程序运行的性能。
线程模型:
![](https://app.yinxiang.com/shard/s33/res/38bcf395-efd4-426f-97cd-90e5d00d86ac.png?resizeSmall&width=572)
所有的线程都共享进程的地址空间,除此之外,所有的线程还共享同一个打开的文件集,子进程、报警已经相关信号。包括同一个网络接口。
线程主要分为两种:用户级线程和内核级线程。
![](https://app.yinxiang.com/shard/s33/res/d37188ac-db51-4a58-9872-c8162b05c498.png?resizeSmall&width=572)
用户级线程可有用户自行编写相关的调度算法,并且在硬件不支持多线程的机器上同样可以使用,并且用户级线程比内核级线程更快。其中一个线程阻塞,则这个进程阻塞。
内核级线程由操作系统调用,多个线程可以争取到更多的时间片。缺点是上下文切换耗时,资源消耗较大。
混合模式:
![](https://app.yinxiang.com/shard/s33/res/b632b7d3-efa9-4009-95de-04e37fbf435b.png?resizeSmall&width=572)
3进程间通信
为什么进程间要通信?
竞争条件,多个进程协作完成某个任务,这个时候就需要进程间的通信来保证任务的完成,这些协作的进程可能共享的读写一些公共的共享的存储区。
凡事涉及共享内存、共享文件以及共享任何资源的情况都会引发同步问题,我们需要互斥的访问这些共享的资源。
我们对共享内存进行访问的程序片段称作临界区域或临界区。那么下面的问题就是如何实现对临界区进行互斥访问了。
忙等待的互斥:
1.屏蔽中断。
使每个进程在刚刚进入临界区后立即屏蔽所有中断,并在就要离开之前再打开中断。缺点很多,基本不能适用。
2锁变量
设想有一个共享锁变量,其初始值为0,当一个进程想进入临界区时,它首先测试这把锁,如果是0,则该进程将其设置为1并进去临界区,若为1,则等待其为0。缺点:没有考虑并发的情况。
3.严格轮换法
![](https://app.yinxiang.com/shard/s33/res/0b90f726-92e7-4082-9fa7-9eeeae50fb1a.png?resizeSmall&width=572)
4.Peterson解法
![](https://app.yinxiang.com/shard/s33/res/677c29fd-a9e0-4f05-903e-3b0f5e7f3dea.png?resizeSmall&width=572)
5.TSL指令
通过硬件来完成互斥,主要的思路是通过锁住数据总线,以禁止其他cpu在本指令结束之前访问内存。
2.3.5信号量
用一个整形变量来累计唤醒的次数,以供后使用。信号量是一个新的类型,他的取值可以是0或者正值。Dijkstra这货建议设立两种操作:down和up(分别表示一般化的sleep和wakeup),对信号量执行down操作,则是检查其值是否大于0,若该值大于0,则将其减1;若该值为0则,使其sleep。
2.3.6互斥量
如果不需要信号量的计数能力,有时可以使用信号量的一个简化版本,称为互斥量。
2.3.7管程
管程有一个很重要的特性,即任意时刻管程中只能有一个活跃的进程,这个一特性使管程能有效的完成互斥。
·························调度·························
调度算法的目标:
所有系统:
公平------给每个进程公平的cpu份额
策略强制性执行-------看到所宣布的策略执行
平衡-------保持系统的所有部分都忙碌
批处理系统:
吞吐量------------每小时最大作业数
周转时间----------从提交到终止时间的最小时间
cpu利用率---------保持cpu始终忙碌
交互式系统:
响应时间---------快速响应请求
均衡性------------满足用户的期望
实时系统:
满足截止时间-------------避免丢失数据
可预测性-------------在多媒体系统中避免品质降低
批处理系统中的调度:
1.先来先服务
2.最短作业优先
![](https://app.yinxiang.com/shard/s33/res/159d08d6-ad17-43e0-bf9e-b9b5c2f3f667.png?resizeSmall&width=572)
3.最短剩余时间优先
最短作业优先的一个抢占版本是最短剩余时间优先算法,调度程序总是选择剩余运行时间最短的那个进程运行。
交互式系统中的调度
1.轮转调度
每个进程被分配一个时间段,称为时间片,即允许该进程在该时间段中运行。如果在时间片结束时该进程还在运行,则将剥夺cpu并分配给另一个进程。
![](https://app.yinxiang.com/shard/s33/res/fad95b1a-c8ec-48b7-a623-c82949ba92fd.png?resizeSmall&width=572)
2.优先级调度
![](https://app.yinxiang.com/shard/s33/res/e0e8eb1b-b541-46e5-bae3-5c2678d5d39f.png?resizeSmall&width=572)
3.多级队列
属于最高级别的运行一个时间片,属于次高级别的运行2个时间片,再次一级的运行4个时间片,以此类推。
4.最短进程优先
通过运行最短的作业使响应时间最短。
5.保证调度
保证每个进程都获取相同的cpu时间片。
6.彩票调度