现代操作系统——进程与线程

前言:

现代操作系统这本书,也是列入了我的书单,早就打算读了,结果发现里面的内容有些讲的太细了,因此有些觉得暂时难以接触的部分是非常快速的阅读过去的。即使这样,读完这本书还是花了我一个月的时间,经典的书籍确实需要细读。

现在书其实是已经读完了,现在来写博客,目的是再巩固一次所学的知识,毕竟这些底层的内容大部分时候是不用的,也容易忘记。

我的github:

我实现的代码全部贴在我的github中,欢迎大家去参观。

https://github.com/YinWenAtBIT

进程:

一、定义

在进程模型中,计算机上所有可以运行的软件,通常包括操作系统,被组织成若干顺序进程,简称进程。在UNIX中,进程和它所有的子女以及后羿共同组成一个进程组,当用户从键盘发出一个信号时,该信号被送给与该键盘相关的进程组里的所有成员。

二、进程的状态与实现

1. 进程的状态:

a. 运行态:该进程此刻正实际占用CPU

b. 就绪态:可运行,但是因为其他进程正在运行而暂停终止

c. 阻塞态:除非某外部事件发生,否则该进程不能运行

其中,阻塞态只能转化成就绪态,就绪太只能转化成运行态。

2. 进程的实现:

为了实现进程模型,操作系统维护着一张表格,即进程表。

每个进程占用一个进程表项,该表项包含了进程状态的总要信息:

a. 程序计数器

b. 堆栈指针

c. 内存分配状况

d. 所打开文件状态

e. 账号和调度信息

f. 运行态转变为阻塞或者就绪态必须保持的信息

这样,进程就能保证再次启动,就好像从来没有被中断过一样。

线程:

一、经典线程模型

1. 理解进程的一个角度是,用某种方法把相关的资源集中在一起。进程又乘法程序正文和数据以及其他资源的地址空间。

2.进程拥有一个执行线程,通常简写为线程,在线程中有一个程序计数器,用来记录接着要执行哪一条指令,线程拥有计数器,自己的堆栈。多个线程共享一个地址空间和其他的进程资源。


线程可以共享进程上述的所有资源。

3. 线程同样可以处于四种状态:

运行、阻塞、就绪、终止。

4. 线程可以通过调用pthread_exit退出或者pthread_yield放弃使用CPU

二、用户空间中实现线程

1. 通用结构:


内核在这里只管理进程,因此只有进程表,没有线程表。线程表由进程自行管理。

2.线程表:

线程表与进程表类似,不过它仅仅记录各个线程的属性,如线程的程序计数器,堆栈指针,寄存器,状态等等。

3. 线程切换:

由于线程切换是在用户控件进行的,因此切换的速度要比内核级线程快一个数量级。这是使用用户级线程包的极大优点。

另一个优点就是用户级线程可以制定自己的调度算法。

二、在内核中实现线程

1.通用模型


该模型中,内核拥有线程表,保存了每个线程的信息。

3. 混合实现:

有一种混合的实现方式,多个用户线程对应一个内核线程。

进程间通信:

一、竞争条件:

两个或多个进程读写某些共享数据,而最后的结果取决于进程运行的精确时序,称为竞争条件。

二、临界区:

1.定义:

我们把对共享内存进行访问的程序片段称为临界区。

2. 避免竞争条件的要求:

a. 两个进程不能同时处于临界区

b. 不应该对CPU 的速度和数量做出任何假设

c. 临界区外运行的进程不得阻塞其他进程

d. 不得使进程无限期等待进入临界区

三、互斥方案:

1. 屏蔽中断:

进程在进入临界区之后立刻屏蔽所有中断,在离开之前打开所有中断。这个方案不好,因为把屏蔽中断的权利交给用户不明智,并且在多处理器情况下,只屏蔽该进程使用的CPU并没有用。

2. 锁变量:

假设有一个共享变量,进程在进入之前测试变量是否为0,为0则进入并设置变量为1。

该方法不能保证一个进程测试结束之后被抢占,另一个进程同时测试的情况出现。

3.严格轮换法:

两个进程测试同一个变量,一个在变量为0时进入临界区,另一个在变量为1时进入临界区。这样的方式为忙等待。该方式浪费CPU时间,通常应该避免。用于忙等待的锁,称为自旋锁。

4. Peterson解法:

使用了一个巧妙的方式,完成了进程使用自己的参数进入临界区,并且发送冲突时,后进入的进程有效的方式。

5. TSL指令:

该指令测试并加锁,该字的读写是不可分割的,指令结束之前,其他的处理器不能访问该内存字。

四、生产者消费者问题:

该问题是两个进程共享一个公共的固定大小的缓冲区。其中一个是生产者,将消息放入缓冲区,另一个是消费者,将消息取出缓冲区。

五、信号量:

1. 信号量定义:

信号量的取值可以是0或者正值,检查数值,修改变量值以及可能发生的睡眠操作均作为单一的,不可分割的原子操作。

2. 使用信号量来解决生产者消费者问题:

使用三个信号量,即可。

3. 互斥量:

互斥量是信号量的简化版本,只有一个数值。

六、条件变量

线程中的同步,除了使用信号量,互斥量以外,还可以使用条件变量。

1.使用:

条件变量与互斥量经常一起使用,先让一个线程锁住一个互斥量,然后当无法获得所需的结果时,等待一个条件变量。此时被锁住的互斥量将被解锁。然后另一个线程锁住互斥量,完成它的操作之后给条件变量发送一个信号,这个线程释放它锁住的互斥变量后,条件变量将会获得互斥锁。

2.注意:

条件变量不会存在内存中。如果一个信号量传递给一个没有线程在等待的条件变量,那么这个信号就会丢失,需要小心避免丢失信号量。

3. 管程:

这是一种高级同步原语,它由过程,变量,以及数据结构组成一个集合。但是大多数编程语言中没有管程这个概念。

调度:

一、调度介绍

1. 定义:

几个进程处于就绪状态时,需要选择一个运行,完成选择工作的这一部分就叫做调度。

2. 进程行为:

在计算上花费了绝大多数时间的进程称为计算密集型,

在等待IO上花费了绝大多数时间的称为IO密集型。

二、何时调度

1.在创建新进程后,调度父进程还是子进程

2. 一个进程退出后必须做出调度决策

3. 当一个进程在IO或者信号量或者其他原因阻塞时,选择另一个进程运行。

4. IO中断时,必须进行调度。

三、调度算法分类

1.批处理:

批处理主要用于周期性作业

a,先来先服务:

该算法是最简单非抢占式算法,先来先服务,按照任务提交的顺序来使用CPU,遇到进程阻塞时,进程被移动到列表最后一个。

b.最短作业优先:

运行时间可以预知时才可以使用此算法

c. 最短剩余时间优先:

该算法是可以抢占版本的最短作业优先算法,当新来的任务比当前运行的任务剩余时间短时,新任务可以抢占运行。

2. 交互式系统中的调度:

a. 轮转调度:

每个进程被分配一个时间段,被称为时间片。时间片通常设置在20-50ms之间。

b. 优先级调度:

优先级高的进程可以先运行,正在运行的程序会随着运行优先级降低。

c. 多级队列

d. 最短进程优先:

e.保证调度

f. 彩票调度

3. 实时系统中的调度:

外部的一种或者多种物理设备给了计算机一个刺激,计算机必须在一个确定的时间范围内做出反应。

实时系统又可以分成硬实时和软实时。

四、调度策略与机制:

将调度策略与调度机制分开,调度算法以某种方式参数化,而用户来填写这些参数。

在实时系统中,乱转调度和优先级调度更为常用

经典IPC问题:

一、哲学家就餐问题:

需要考虑死锁,以及是否能达到最大就餐人数的问题。

具体的解法很精妙,再此处不介绍

二、读写者问题:

该问题有两个版本,一个是写着优先,一个是读者优先。解决问题的办法是使用互斥量来约束读者写着进入使用资源,以及限制读写者进入队列排队的方式。

总结:

进程和线程之间的区别弄清楚之后,还需要仔细了解其可以访问的资源。以及解决他们之间的通信,调度问题。再次之上又有经典的生产者消费者问题,哲学家就餐问题,读写者问题。理解了这些问题之后,才能真正的算对进程线程有了深入的理解。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值