操作系统-进程管理(信号量机制)

进程的描述与控制

前趋图和程序执行

前趋图

前趋图是一个有向无环图(DAG),用于描述进程之间执行的先后的关系
结点:描述一个程序段或进程,或一条语句
**有向边:**结点之间的偏序或前序关系“——>”,Pi——>Pj,则Pi是Pj的直接前趋,Pj是Pi的直接后继
**注意:**前趋图中必须不存在循环

程序的顺序执行

一个程序由若干个程序段组成,而这些程序段的执行必须是顺序的,这种程序执行的方式就称为程序的顺序执行。
特征:

  • 顺序性:处理机的操作严格按照程序所规定的顺序执行
  • 封闭性:程序一旦开始执行,其计算结果不受外界因素的影响
  • 可再现性:程序执行的结果与它的执行速度无关(即与时间无关),而只与初始条件有关

程序的并发执行

特征:

  • 间断性:在多道程序设计的环境下,程序的并发执行,以及为完成一项任务而相互合作,这些程序之间要共享系统的资源,形成了相互制约的关系。相互制约导致并发程序具有“执行—暂停—执行”这种间断性的活动规律。
  • 失去封闭性:程序在并发执行时,系统的资源状态由多道程序来改变,程序运行失去封闭性。一程序的运行受到其他程序的影响。
  • 不可再现性:程序在并发执行时,多次运行初始条件相同的同一程序会得出不同的运行结果。例:共享公共变量的两个程序,它们执行时可能产生不同结果。
    在这里插入图片描述

在这里插入图片描述

进程的描述

进程的特征和定义

进程:程序关于某个数据集合的一次执行过程
特征:

  • 结构特征:进程控制块(PCB) + 程序 + 数据 = 进程实体
  • 动态性——最基本的特征:进程:进程实体的一次执行过程,有生命周期。程序:程序是一组有序指令的集合,是静态概念
  • 并发性
  • 独立性
  • 异步性:进程按各自独立的、不可预知的速度向前推进
    ###进程的三种基本状态
  • 就绪状态:进程已获得除CPU之外的所有必需的资源,一旦得到CPU控制权,立即可以行。
  • 运行状态: 进程已获得运行所必需的资源,它的程序正在处理机上执行
  • 阻塞状态:正在执行的进程由于发生某事件而暂时无法执行时,便放弃处理机而处于暂停状态,称该进程处于阻塞状态或等待状态
    在这里插入图片描述

挂起状态

引起挂起状态的原因:

  • 终端用户的请求
  • 父进程请求
  • 负荷调节的需要
  • 操作系统的需要
    进程状态的转换:
    引入挂起状态后,增加了挂起状态(静止状态)到非挂起状态(活动状态)的转换,或者相反
  • 活动就绪–>静止就绪
  • 活动阻塞–>静止阻塞
  • 静止就绪–>活动就绪
  • 静止阻塞–>活动阻塞
    在这里插入图片描述

进程管理中的数据结构

进程控制块(PCB)的作用

存放进程管理和控制信息的数据结构称为进程控制块。它是进程管理和控制的最重要的数据结构,在创建时,建立PCB,并伴随进程运行的全过程,直到进程撤消而撤消。PCB就象我们的户口。
PCB是进程存在的唯一标志。
系统的所有PCB组织成链表或队列,常驻内存的PCB区。

进程控制块中的信息

进程标示符
每个进程都必须有一个唯一的标识符
内部标示符
外部标示符
处理机状态:
处理机状态信息主要由处理机的各种寄存器中的内容组成。处理机运行时的信息存放在寄存器中,当被中断时这些信息要存放在PCB中。

  • 通用寄存器

  • 指令计数器

  • 程序状态字

  • PSW用户栈指针
    进程调度信息:

  • 进程状态

  • 进程优先级

  • 进程调度所需的其他信息

  • 事件
    进程控制信息:

  • 程序和数据的地址

  • 进程通信和同步机制

  • 资源清单

  • 链接指针
    进程控制块的组织方式:

  • 线性方式

  • 链接方式:吧具有相同状态的PCB通过其中的链接字链接成一个队列
    在这里插入图片描述

  • 索引方式:系统根据所有进程的状态建立几张索引表,吧各个表的内存首地址记录在内存的专用单元中。索引表的表目中记录了相应状态的某个PCB在PCB表中的地址。
    在这里插入图片描述

进程控制

进程图:
在这里插入图片描述
引起创建进程的事件:
多道程序环境中,只有进程才能在系统中运行:
用户登录、作业调度、提供服务、应用请求
进程的创建:
调用进程创建原语Create()创建新进程
进程创建的过程:
申请空白PCB——为新进程分配资源——初始化进程控制块——将新进程插入就绪队列
进程的终止:
1、引起终止的事件:
正常结束、异常结束(越界错误、非法指令等)、外界干预(操作员或者操作系统干预、父进程请求、父进程终止)
2、进程终止的过程:
找出被终止进程的PCB ——
若进程状态为运行态,置CPU调度标志为真——
若其有子孙进程,终止其子孙进程并回收其资源——
回收终止进程的资源 ——
回收终止进程的PCB

进程的阻塞与唤醒

  1. 引起进程阻塞和唤醒的事件
    1)请求系统服务 2)启动某种操作
    3)新数据尚未到达 4)无新工作可做
  2. 进程阻塞过程
    调用阻塞原语阻塞自己;
    将PCB中的状态改为阻塞,并加入阻塞队列;
    转进程调度。
  3. 进程唤醒过程
    把阻塞进程从等待该事件的阻塞队列中移出;
    置进程状态为就绪态,将PCB插入到就绪队列中。
    阻塞原语与唤醒原语作用相反,成对使用

原语:
原语是在操作系统中调用核心层子程序的指令。. 与一般广义指令的区别在于它是不可中断的,而且总是作为一个基本单位出现。. 它与一般过程的区别在于:它们是“ 原子操作 (primitive or atomic action)”。. 所谓原子操作,是指一个操作中的所有动作要么全做,要么全不做。. 换言之,它是一个不可分割的基本单位,因此,在执行过程中不允许被中断。. 原子操作在管态下执行,常驻内存。. 原语的作用是为了实现进程的通信和控制,系统对进程的控制如不使用原语,就会造成其状态的不确定性,从而达不到 进程 控制的目的

进程的挂起与激活

  1. 进程的挂起过程
    检查被挂起进程的状态:
    若处于活动就绪,则改为静止就绪;
    若处于活动阻塞,则改为静止阻塞;
    若挂起的进程正在执行,则重新进行进程调度。
  2. 进程的激活过程:
  1. 激活原语先将进程从外存调入内存;
  2. 检查该进程的状态:
    若为静止就绪,则改为活动就绪;
    若处于静止阻塞,则改为活动阻塞。

进程同步

概念:

  1. 进程间两种形式的制约关系
    (1) 间接相互制约关系 — 源于资源共享
    (2) 直接相互制约关系 — 源于进程合作

  2. 临界资源 — 互斥访问

  3. 临界区
    临界区:每个进程中访问临界资源的那段代码
    访问临界区的程序设计为:
    对欲访问的临界资源进行检查,
    若此刻未被访问,设正在访问的标志 ……进入区
    访问临界资源 ……临界区
    将正在访问的标志恢复为未被访问的标志 ……退出区
    其余部分 ……剩余区

  4. 同步机制应遵循的规则
    空闲让进
    忙则等待
    有限等待
    让权等待

信号量机制

1、整型信号量:
定义:整型量,除初始化外,仅能通过两个原子操作来访问
P操作:wait(S)😛(S)

while(S<=0)do no-p;
S--;

V操作 signal(S):V(S)

S++;

PV操作是原子操作不可中断

semaphore  mutex =1;
        begin
        parbegin
            process 1: begin
                 repeat
                 wait(mutex);
                 critical section
                  signal(mutex);
                   remainder section
                  until false;
                     end
            process 2: begin
                 repeat
                 wait(mutex);
                 critical section
                 signal(mutex);
                  remainder section
                  until false; 
                  end
        parend       


缺点:没有遵循让权等待原则
2、记录性信号量:
引入整型变量value(代表资源数目)、进程链表List (链接所有等待进程)
记录型数据结构:

typedef  struct{
              int value;
              struct process_control_block * list;
       } semaphore;

在这里插入图片描述
在这里插入图片描述
缺点:共享的资源越多,死锁的可能性越大
3、AND型信号量
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

生产者消费者问题

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
empty的初始值应该为缓存区的最大容量,当empty的值>0的时候生产者才可以进行放入操作,full的初始值应该是零,在刚开始时候缓存区的产品为零,消费者是无法取走产品的,而信号量mutex的值应该为1,通过它实现了生产者间,消费者间互斥
本情景是生产者间消费者间互斥的使用缓存区
每个程序中的多个wait操作的顺序不能颠倒。应该先执行对资源信号量的wait操作,再执行对互斥信号量的wait操作,否则可能会引起进程的死锁!

通过AND信号量解决

Int in=0, out= 0;

semaphore  mutex=1,empty=n,full=0;
Void producer(){ 
 	do{
                   Swait(empty, mutex);
                   buffer[in]=nextp;
                   in=(in+1) mod n;
                   Ssignal(mutex, full);
	}while(TRUE)
}
Void consumer(){ 
    do{
	Swait(full, mutex);
           nextc:=buffer[out];
           out=(out+1) mod n;
           Ssignal(mutex, empty);
                                   
      }while(TRUE)
   }
Void main(){
	cobegin
	    proceducer();
 	    consumer();
	coend
}

通过信号量集解决

Int in=0, out= 0;

semaphore  mutex=1,empty=n,full=0;
Void producer(){ 
 	do{Swait(empty,1,1; mutex,1,1);
                   buffer[in]=nextp;
                   in=(in+1) mod n;
                   Ssignal(mutex,1; full,1);
	}while(TRUE)
}
Void consumer(){ 
    do{
           Swait(full,1,1; mutex,1,1);
           nextc:=buffer[out];
           out=(out+1) mod n;
           Ssignal(mutex,1; empty,1);
                                   
      }while(TRUE)
   }
Void main(){
	cobegin
	    proceducer();
 	    consumer();
	coend
}

哲学家进餐问题:

五个哲学家共用一张圆桌,分别坐在周围的五张椅子上,在桌子上有五只碗和五只筷子,他们的生活方式是交替地进行思考和进餐。平时,一个哲学家进行思考,饥饿时便试图取用其左右最靠近他的筷子,只有在他拿到两只筷子时才能进餐。进餐毕,放下筷子继续思考。

可见:相邻两位不能同时进餐;
最多只能有两人同时进餐
如果使用记录型信号量解决

semaphore stick[5]={1,1,1,1,1};
do{
	wait(stick[i]);
	wait(stick[(i+1)%5]);;
	
	signal(stick[i]);
	signal(stick[(i+1)%5]);
	i++;
	}while(TRUE);

可见当五个哲学家都拿左边筷子时,就会将筷子全部拿完,而无法进行拿右边筷子,造成了进程的死锁

所以第一种方法就是让哲学家同时拿到左右筷子,吃完后再同时释放两根筷子,这样就避免了死锁问题

semaphore stick[5]={1,1,1,1,1};
do{
	Swait(stick[i],stick[(i+1)%5]);;
	
	signal(stick[i],stick[(i+1)%5]);
	
	i++;
	}while(TRUE);

但是:当题目要求,欸!我就是让你用记录性信号量来实现则,将哲学家分为奇偶,奇数哲学家先拿左边的再拿右边的,偶数哲学家先拿右边的后拿左边的就可以完美的实现

semaphore chopstick[5]={1,1,1,1,1};
      第i 位哲学家的活动可描述为:
 do{
     if  i mod 2=1 {
          wait(chopstick[ i ]);
          wait(chopstick[ ( i +1) mod 5] )
        }
     else
        {
          wait(chopstick[ ( i +1) mod 5] );
          wait(chopstick[ i ])
        }
      eat;
      signal(chopstick[ i ]);
      signal(chopstick[(i +1)mod 5]);
      …
      think;
}while(TRUE)

情景三:读者写者问题(敲黑板划重点!!!)

在这里插入图片描述
可以看出:允许多个进程同时读一个共享对象,但不允许一个Writer进程和其他Reader进程或Writer进程同时访问共享对象
“读者——写者问题”是保证一个Writer进程必须与其他进程互斥地访问共享对象的同步问题。
最终实现的就是:读读共享,写写互斥,读写互斥

互斥信号量wmutex: 实现Reader与Writer进程间在读或写时的互斥整型变量Readcount: 表示正在读的进程数目;
由于只要有一个Reader进程在读,便不允许Writer进程写。 ∴仅当Readcount=0,即无Reader进程在读时,Reader才需要执行Wait(wmutex)操作。若Wait(wmutex)操作成功,Reader进程便可去读,相应地,做Readcount+1操作。
同理,仅当Reader进程在执行了Readcount减1操作后其值为0时,才需执行signal(wmutex)操作,以便让Write进程写。

互斥信号量rmutex: Reader进程间互斥访问Readcount

semaphore rmutex=1, wmutex =1;
int readcount =0;
Void Reader(){
             do{
                wait(rmutex);
                if (Readcount==0) 
				wait(wmutex);
                Readcount ++;
                signal(rmutex);
                   …
                   读;wait(rmutex);
                Readcount - -;
                if (Readcount==0) 
				signal(wmutex);
                signal(rmutex);
            }while(TRUE);
}

Void writer(){
     do{
         wait(wmutex);;
         signal(wmutex);
     }while(TRUE);
}

Void main(){
   Cobegin
       reader();  writer();
   Coend
}

利用信号量集机制实现

int RN;
semaphore  L=RN, mx= 1;
Void reader() {
            do{
               Swait(L, 1, 1);
               Swait(mx, 1, 0);
               …
               读;Ssignal(L, 1);
            }while(TRUE)
   }

Swait(mx, 1, 0)语句起着开关的作用。只要无writer进程进入写,mx=1,reader进程就都可以进入读。但只要一旦有writer进程进入写时,mx=0,则任何reader进程就都无法进入读。

Void writer(){ 
   do{
       Swait(mx, 1, 1; L, RN, 0);;
       Ssignal(mx, 1);
   }while(TRUE)
}

Swait(mx, 1, 1; L, RN, 0)语句表示仅当既无writer进程在写(mx=1),又无reader进程在读(L=RN),writer进程才能进入临界区写。

Void main(){
   cobegin
       reader();  writer();
Coend
}

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值