操作系统笔记—进程的同步与互斥

操作系统——进程的同步与互斥

进程同步:保证各个进程按预期的方式推进。又称直接制约关系,需要协调他们的工作次序。

临界资源:一个时间段内只允许一个进程使用(摄像头,打印机等)

进程互斥:对于临界资源的访问,必须互斥地执行,也称简介制约关系。

对临界资源的访问,逻辑上可以分为进入区(检查是否可以进入临界区,如果可以进入,则进行上锁),临界区(访问临界资源的代码),退出区(解锁),剩余区(其他处理)。

为了实现临界资源互斥访问,同时保证系统性能。需要遵循以下原则:

1.空闲让进,临界区空闲时,可以允许一个请求进入临界区的进程立即进入临界区

2.忙则等待:当已有进程进入临界区时,其他试图进入临界区的进程必须等待

3.有限等待,对请求访问的进程,应保证能在有限时间内进入临界区(保证不会饥饿)

3.让权等待,对进程不能进入临界区时,应立即释放处理机,防止进程忙等待(进程无法推进但占用处理机)

进程互斥的软件实现方法

单标志法:
两个进程在访问完临界区后会把临界区的权限转交给另一个进程(每个进程进入临界区的权限只能被另一个赋予)

,可以实现‘同一时间只有一个进程访问临界区’,但违背了空闲让进的原则。

双标志法:
一个进程表示自己不会进入临界区后交出访问临界区的权限,但由于异步性,两个进程可能同时进入临界区,违背了‘忙则等待’的原则

双标志后检查法:
将双标志法的先检查后上锁改为先上锁后检查,保证了只有一个进程访问临界区,但可能因为异步出现两个进程都无法进入的问题,出现饥饿现象。

Peterson算法:在双标志后检查法的基础上,如果两个进程都想访问临界区,会尝试让对方进程先进入,这种算法解决了进程互斥问题,遵循了空闲让进,忙则等待,有限等待三个原则,但是依然未遵循让权等待的原则。

进程互斥的硬件实现方法

中断屏蔽方法:利用开/关中断指令实现(关中断后不允许当前进程被中断,也就不会发生进程切换;在执行开中断指令后才有可能有别的进程上处理机并访问临界区)

优点:简单高效;缺点:不适合多处理机(开关中断只能中断自身处理机)。只适合操作系统内核进程,不适合用户进程(开关中断是核心态操作)

TestAndSet指令

简称TS指令或TSL指令,这种指令由硬件实现,在执行过程中不允许被中断,只能一气呵成。原理是当有进程访问临界区后,对临界区进行上锁,一直到访问临界区的进程在推出区进行解锁跳出循环。这种方式用硬件方式将上锁和检查操作一气呵成。优点是实现简单,适合多处理机环境,缺点是不满足让权等待的原则。

Swap指令

也称Exchange指令,用硬件实现,执行过程中不允许中断,只能一气呵成。这种方法逻辑上跟TSL指令无太大区别,都是对进入临界区的进程进行上锁

信号量机制

用户可以通过操作系统提供的一对原语来对信号量进行操作,从而很方便的实现了进程互斥,进程同步。

信号量其实就是一个变量(可是是整型,也可以是更复杂的记录型变量),可以用一个信号量来表示系统中某种资源的数量

一对原语:wait(S)和signal(S),可以把原语理解为一个函数,中间的S是调用时的一个参数。这两个函数简称PV操作,分别写为P(S)和V(S)(申请和释放)

整型信号量

用一个整型的变量作为信号量,用来表示系统中某种资源的数量。

`int S = 1  //初始化信号量

	void wait(int S){
	while(S<=0);	//资源不够则一直循环
	S = S-1;	//信号量够就占用一个资源
}

void signal (int S){
	S = S+1;	//使用资源完毕后释放资源
}
`

整型信号量不满足让权等待,可能会出现忙等。

记录性信号量

`
//记录型信号量的定义:
typedef struct {
int value;
struct process *L;
}semphore;

//wait原语
void wait (semaphore S){
	S.value --;
	if(S.value <0){
	block(S.l) //如果剩余资源数不够,使用block原语使进程从运行态切换到阻塞态,并把它挂在信号量S的等待队列(阻塞队列中)
	}
}

void signal (semaphhore S){
	S.value++;
	if(S.value<=0){		//小于等于0指还有别的进程在等待资源
		wakeup(S.L)		//释放资源后,若还有别的进程等待这种资源,则使用wakeup原语唤起队列中的一个进程,这个进程从阻塞态变成就绪态
	}
}
`

信号量机制实现进程互斥,同步,前驱

###实现进程互斥
1.分析并发进程的关键活动,划定临界区

2.设置互斥信号量mutex,初值为1.

3.在临界区之前执行P(mutex)操作;

4.在临界区之后执行V(mutex)操作;

信号量机制实现进程同步

1.分析什么地方需要‘同步关系’,保证一前一后执行两个操作。

2.设置同步信号量S,初始为0

3.在‘前操作’之后执行V(S)

4.在‘后操作’之前执行P(S)

如果要实现前驱关系,要为每一对前驱关系设置同步变量,然后使用进程同步的方式进行。

生产者-消费者问题

系统中有一组生产者进程和消费者进程,生产者进程每次生产一个产品放入缓存区,消费者进程每次从缓存区中取出一个产品并使用(这里的产品指某种数据)

只有缓冲区没满时,生产者才能把产品放入缓冲区,否则(生产者)必须等待;缓冲区空时,消费者必须等待。

缓冲区是临界资源,各进程必须互斥地访问

对生产者来说,每次用P操作消耗一个空闲缓冲区,用V操作增加一个产品;对消费者来说,每次用P操作消费一个产品,用V操作增加一个缓存区。在每个操作之间设置PV操作实现进程互斥。实现互斥的P操作一定要在实现同步的P操作之后。两个V操作不会导致进程阻塞,因此两个V操作顺序可以互换。

读者-写者问题

两个并发进程共享一个文件,当两个或两个以上的读进程共同访问数据时不会产生副作用。但多个写进程同时访问数据可能会导致数据不一样。因此要求:允许多个读者可以同时对文件进行读操作。只允许一个写者往文件里写信息,在任一写者完成操作前不允许其他读者或写者工作,写者执行操作前应该给让所以其余的读者或写者退出。

算法:在上锁前进行判断,第一个读进程负责加锁,最后一个读进程负责解锁,在这两个过程中要设置互斥变量来保证检查与赋值一气呵成。在写进程的前后设置PV,在读进程前设置PV,保证读写进程有序进行,不会出现饥饿。

哲学家就餐问题

圆桌上两个哲学家中间有一根筷子,每个哲学家只能用他两边的筷子吃饭,一旦缺少一根进程就会被阻塞。

算法:设置信号量数组chopstick[5] = {1,1,1,1,1},每个哲学家i左边的筷子编号为i,右边的筷子编号为(i+1)%5.每个哲学家先对左右两边的筷子进行P操作,在完成进程后再对两边进行V操作。

如果不加条件,如果所有哲学家并发用餐就会出现死锁现象。

可以添加的条件:1.限制最大进餐人生;2,对于奇数号哲学家先拿左边的筷子,对于偶数号的哲学家先拿右边的筷子。(用争抢防止阻塞);3.仅当哲学家左右两只筷子都可用时才允许他抓起筷子

管程

管程是一种软件模块,由这些部分组成:

1.局部于管程的共享数据结构说明:

2.对该数据结构进行操作的一组过程;

3.对局部于管程的数据结构设置初始值的语句;

4.管程仅有一个名字

管程的基本特征:

1.局部于管程的数据只能被局部于管程的过程所访问;

2.一个进程只有通过调用管程内的过程才能进入管程访问共享新数据

3.每次仅允许一个进程在管程内执行某个内部过程

管程本质上就是对PV操作进行了封装。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值