操作系统之进程

1 进程的定义

  进程由程序段+数据段+PCB构成的。PCB是进程存在的唯一标志。进程是进程实体的运行过程,是系统进行资源分配的一个独立单位。
进程转态转换

2 进程控制

进程控制

3 进程通信

(1) 共享存储

在这里插入图片描述

(2) 管道通信

在这里插入图片描述

4 进程调度算法

在这里插入图片描述

5 线程

  线程是一个基本的cpu执行单位,也是程序执行流中的最小单位。引入线程后,线程作为cpu调度最小单位,而进程是资源分配最小单位。
线程

6 线程实现方法

在这里插入图片描述

7 进程同步与互斥

  **同步:**并发性带来了异步性,有时需要通过进程同步来解决这种异步问题。有的进程之间需要相互配合地完成工作,各进程的工作推进需要遵循一定的先后顺序。
  **互斥:**对临界资源的访问,需要互斥的进行。即一段时间内只允许一个进程访问该资源。在这里插入图片描述

8 信号量机制

  记录型信号量

typedef struct{
	int                  value;     //剩余资源数
	struct process       *L;        // 等待队列
}semaphore;

void
wait( semaphore S ){        //对信号量S一次p操作表示进程请求一个        
	S.value--;              //单位的的该类资源,S.value<0时表示该类资    
	if( S.value < 0 ){      //源分配完毕,因此进程调用block原语进行自
		block( S.L );       //我阻塞,并插入该类资源的等待队列S.L中
	}
}

void
signal( semaphore S ){     //对信号量进行一次v操作表示进程释放一个该单
	S.value++;             //位的资源,若++后S.value<=0,表示依然有进
	if( S.value <= 0 ){    //程等待该类资源,因此调用wakeup唤醒等待队
		wakeup( S.L );     //列中第一个进程
	}
}

  信号量实现进程同步、互斥和前驱
  互斥:确定临界区;
     设置互斥信号量,初值为1(对于不同的临界区需要设置不同的互斥信号量)
     临界区之前对信号量执行p操作
     临界区之后对信号量执行v操作

  同步:找出需要实现的“一前一后”关系
     设置同步信号量,初值为0(同步信号量的初值要看对应资源的初始值为多少)
     在“前操作”之后执行v操作
     在“后操作”之前执行p操作

  前驱:画出前驱图,把每一对前驱关系都看出同步问题
     为每一对前驱关系设置同步信号量,初值为0
     在每个“前操作”之后执行v操作
     在每个“后操作”之前执行p操作
在这里插入图片描述在这里插入图片描述
  生产者-消费者问题
在这里插入图片描述
在这里插入图片描述

semaphore  mutex = 1; //互斥信号量,实现对缓冲区的互斥访问
semaphore  empty = n; //同步信号量,表示空闲缓冲区数量
semaphore  full = 0;  //同步信号量,表示产品的数量

Producer(){
	while( 1 ){
		生产一个产品;
		p( empty );
		p( mutex );
		把产品放入缓冲区;
		v( mutex );
		v( full );
	}
}

Consumer(){
	while( 1 ){
		p( full );
		p( mutex );
		从缓冲区取出一个产品;
		v( mutex );
		v( mutex );
		使用产品;
	}
}

实现互斥的p操作一定要在实现同步的p操作之后

  多生产者-多消费者问题
在这里插入图片描述

semaphore mutxe = 1; //互斥访问盘子
semaphore apple = 0;
semaphore orange = 0;
semaphore plate = 1; //盘子中还可以放多少水果

dad(){
	while( 1 ){		
		准备一个苹果;
		p( plate );
		p( mutex );
		把苹果放入盘子里;
		v( mutex );
		v( apple );
	}
}

mom(){
	while( 1 ){		
		准备一个橘子;
		p( plate );
		p( mutex );
		把橘子放入盘子里;
		v( mutex );
		v( orange );
	}
}

daughter(){
	while( 1 ){
		p( plate );		
		p( mutex );
		从盘子里取出苹果;
		v( mutex );
		v( plate );
		吃掉苹果;
		
	}
}

son(){
	while( 1 ){
		p( orange );
		p( mutex );
		从盘子里取出橘子;
		v( mutex );
		v( plate );
		吃掉橘子;
	}
}

如果缓冲区大小大于1,就必须专门设置1个互斥信号量mutex,来保证互斥访问缓冲区。

  吸烟者问题
在这里插入图片描述

semaphore offer1 = 0;
semaphore offer2 = 0;
semaphore offer3 = 0;
semaphore finsh = 0;
int i = 0;          //用于实现3个吸烟者轮流吸烟

provider(){
	while( 1 ){
		if( i == 0 ){
			将组合1放桌子上;
			v( offer1 );
		} else if( i == 1 ){
			将组合2放入桌子上;
			v( offer2 );
		}else if( i == 2 ){
			将组合3放入桌子上;
			v( offer3 );
		}
	}
	i = ( i + 1) % 3;
	p( finsh );
}

smoker1(){
	while( 1 ){
		p( offer1 );
		从桌子上拿走组合1,卷烟,抽掉;
		v( finsh );
	}
}

smoker2(){
	while( 1 ){
		p( offer2 );
		从桌子上拿走组合2,卷烟,抽掉;
		v( finsh );		
	}
}

smoker3(){
	while( 1 ){
		p( offer3 );
		从桌子上拿走组合3,卷烟,抽掉;
		v( finsh );		
	}
}

  读者-写者问题

semaphore rw = 1;     //用于实现对文件的互斥访问
int count = 0;        //记录当前有几个读进程在访问文件
semaphore mutex = 1;  //用于保证对count变量的互斥访问
semaphore w = 1;      //用于实现“读写公平”

writer(){
	while( 1 ){
		p( w );
		p( rw );
		写文件;
		v( rw );
		v( w );
	}
}

reader(){
	while( 1 ){
		p( w );
		p( mutex );
		if( count == 0 )
			p( rw );
		count++;
		v( mutex );
		v( w );
		读文件;
		p( mutex );
		count--;
		if( count == 0 )
			v( rw );
		v( mutex );
	}
}

9 管程

  管程是一种特殊设计的软件模块,由这样部分组成:
    1.局部于管程的共享数据结构说明
    2.对该数据结构进行的一组操作过程
    3.对局部于管程的共享数据设置初始值的语句
    4.管程有一个名字

  管程的基本特征:
    1.局部于管程的数据只能被局部于管程的过程所访问
    2.一个进程只有通过调用管程内的过程才能进入过程访问共享数据
    3.每次仅允许一个进程在管程内执行某个内部过程(由编译器负责实现
管程解决生产者-消费者问题

monitor ProducerConsumer
	condition full,empty;   //条件变量用来实现同步(排队)
	int count = 0;          //缓冲区中的产品数
	
	void insert( Item item ){ //把产品item放入缓冲区
		if( count == N )
			wait( full );
		count++;
		insert_item( item );
		if( count == 1 )
			signal( empty );
	}
	
	Item remove(){
		if( count == 0 )
			wait( empty );
		count--;
		if( count == N - 1 )
			signal( full );
		return remove_itrm();
	}
end monitor;

//生产者进程
producer(){
	while( 1 ){
		item = 生产一个从产品;
		ProducerConsumer.insert( item );
	}
}

//消费者进程
consumer(){
	while( 1 ){
		item = ProducerConsumer.remove();
		消费产品item;
	}
}

10 死锁

  死锁:各进程相互等待对方手里的资源,导致各进程都阻塞,无法向前推进的现象。
  饥饿:由于长期得不到想要的资源,某进程无法向前推进的现象。
预防死锁:
在这里插入图片描述

银行家算法

  安全序列:所谓安全序列,就是指如果系统按照这种序列分配资源,则每个进程都能顺利完成。只要能找出一个安全序列,系统就是安全状态。当然,安全序列可能有很多个。
在这里插入图片描述
假设系统中有n个进程,m个资源
每个进程在运行前先声明对各种资源的最大需求数,则可用一个nm的矩阵(可用二维数组)表示所有进程对各种资源的最大需求数。不妨称为最大需求矩阵MAX,MAX[i,j]=K表示进程pi最多需求K个资源Rj。同理,系统可用一个nm的分配矩阵Allocation表示对所有进程的资源分配情况。MAX-Allocation=Need矩阵,表示各进程最多还需要多少各类资源。另外,还要用一个长度为m的一维数组Available表示当前系统中还有多少可用资源。
某进程pi向系统申请资源,可用一个长度为m的一维数组Requesti表示本次申请的各种资源量。
在这里插入图片描述
可用银行家算法预判本次分配是否会导致系统进入不安全状态:
1.如果Requesti[j]<=Need[i,j] (0<=j<=m)便转向2,否则认为出错;
2.如果Requesti[j]<=Available[j] (0<=j<=m)便转向3;否则表示尚无足够资源,pi必须等待;
3.系统试探着把资源分配给进程pi,并修改相应的数据(并非真的分配,修改数值只是为了做预判):
Available = Available - Requesti
Allocation[i,j] = Allocation[i,j] + Requesti[j];
Need[i,j] = Need[i,j] - Requesti[j]
4.操作系统执行安全性算法,检查此次资源分配后,系统是否处于安全状态。若安全,才正式分配;否则,恢复相应数据,让进程阻塞。
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值