操作系统进程同步

Posted 桃陉

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了操作系统进程同步相关的知识,希望对你有一定的参考价值。


1.进程的互斥

进程互斥是进程同步控制中的一种特例。

1.1临界资源和临界区

临界资源:某段时间内只允许一个进程使用的资源。

临界区:使用临街资源的那一部分程序。

1.2遵循准则

为了提供对互斥的支持,系统必须满足以下条件:

(1)空闲让进:某进程退出临界区,刚好有其他进程等待进入临界区,那么就让它进入。

(2)忙则等待:有进程在临界区中,其他进程必须进行等待。

(3)有限等待:不能让一个进程在临界区中无限运行,在有限时间内让它退出。

(4)让权等待:如果有优先级更高的进程在等待区中,那么就让临界区的进程让位。

1.3使用硬件实现互斥

中断禁用:保证进程进入临界区后不被打断,有效的实现互斥。

while(true)
{
	/*禁用中断*/
	  临界区
	/*启用中断*/
}

缺点:
(1)代价太高,会降低执行效率
(2)不能用于多核处理器结构

专用机器指令:compare_and_swap 指令

优点:
(1)适用范围广
(2)使用简单
(3)可支持多个临界区

缺点:
(1)导致CPU空耗,当一个进程等待进入临界区时,会不断地持续检测
(2)导致饥饿进程,都有多个进程都等待进入临界区是,在某些极端情况下可能会导致某个进程永远无法进入临界区。

1.4信号量实现互斥

信号量是一个数据结构,简写为s。主要有两个原语操作wait和signal。

原语wait(s):用于申请一个资源,有时候写为P

void wait(semaphore s)
{
	//申请时,资源数减一,如果此时资源数小于0,说明无空闲资源,那么将进程阻塞,并将其放入等待队列
	s.value=s.value-1;
	if(s.value<0)
		block(s.queue);
}

原语signal(s):用于释放一个资源,有时候写为V

void signal(semaphore s)
{
	//将资源数加一,如果此时资源数小于等于0,那么将进程唤醒,并将其放入就绪队列
	s.value=s.value+1;
	if(s.value<=0)
		wakeup(s.queue);
}

信号量的物理含义:在使用时对信号量进行初始化,注意初始值应该大于等于0。

在使用wait和signal原语时需要注意使用顺序,否则可能会出现死锁。


2.进程的同步

在使用信号量实现进程同步时,一个信号量需要和一个消息对应起来。

2.1生产者\\消费者问题

问题描述:生产者生产产品放入缓冲区中,当缓冲区满时则发生阻塞。消费者从缓冲区中取出产品,当缓冲区为空时,则发生阻塞。

解决方案:这里我们设置三个信号量,S1、mutex、S2,分别表示缓冲区是否还有空位、该时刻只可以进行一个操作(生产或者消费)、缓冲区是否已满;定义两个变量i和j分别指向生产产品的位置和消费产品的位置。

2.2读者\\写者问题

问题描述:读者和写者共享一组数据区,允许多个读者同时执行读操作,不允许读者、写者同时操作,不允许多个写者同时操做。

解决方案:假设读优先,即有写着等待,但是有其他读者读,那么新读者也可以进行读操作。设置信号量w用于读者和写者、写者和写者之间的互斥;设置信号量readcount表示正在读的读者个数;设置mutex来对readcount这个临界资源的互斥访问。


3.进程之间的通信

进程之间根据通信内容可以分为控制信息的传送大批量数据的传送;根据高级通信机制可以分为:共享内存方式管道通信机制消息传递机制

3.1共享内存方式

使用共享内存可以避免对一个内容的反复访问,但是要注意实现存储区访问的互斥。

3.2管道通信机制

管道通信用于连接一个读进程和一个写进程,实现进程之间通信的一种共享文件,又称为pipe文件。

以字符流形式将大量数据送入管道,它可以传送大量数据,因此被广泛采用。

3.3消息传递机制

以信息为单位,可以分为直接通信方式和间接通信方式。

直接通信方式:发送进程直接将消息发给接受进程,接受进程可以接受任意发送发的消息,并且知道发送方是谁。

简介通信方式:消息并不直接送达,而是发送到临时消息队列(信箱)。具有很大的灵活性,可以一对一、一对多、多对多、多对一。


4.管程

把分散在各进程中的临界区集中起来进行管理,防止进程有意或者无意的违法同步操作。


5.思维导图

以上是关于操作系统进程同步的主要内容,如果未能解决你的问题,请参考以下文章

互斥与同步

多线程编程

进程线程同步异步

进程同步

LINUX PID 1和SYSTEMD PID 0 是内核的一部分,主要用于内进换页,内核初始化的最后一步就是启动 init 进程。这个进程是系统的第一个进程,PID 为 1,又叫超级进程(代码片段

java基础入门-多线程同步浅析-以银行转账为样例