进程间通信基本概念【操作系统】

进程间通信的目的:

1.数据传递

2.资源共享

3.通知事件

进程间通信的发展历史:

1.管道

2.SystemV

3.POSIX(可移植操作系统接口)

管道:

1.匿名管道pipe

2.命名管道

SysV IPC:

1.消息队列

2.共享内存

3.信号量

POSIX IPC:

1.消息队列

2.共享内存

3.信号量

4.互斥量

5.条件变量

6.读写锁

Socket :(进程间通信)

进程间共享的几种方式:


1.左边两个进程共享存留于文件系统中某个文件上的某些信息,为了访问这些信息,每个进程都得穿越内核如(read、write、lseek等)。当一个文件有待更新时,某种形式的同步是需要的,这样既可以保护多个写入者,防止相互串扰,也可以保护一个或多个读者,防止写入者的干扰。

2.中间两个进程共享驻留于内核中的某些信息。管道是这种共享类型的典型例子。现在访问共享信息的每次操作都涉及向内核的一个系统调用。

3.右边两个进程有一个双方都能访问的共享内存区。每个进程一旦设置号该共享内存区,就能根本不涉及内核而访问其中的数据,共享该内存区的进程需要某种形式的同步

IPC对象的持续性:

1.随进程持续性的 IPC   :一直存在到打开着该对象的最后一个进程关闭该对象为止。如管道和FIFO;

2.随内核持续性的IPC  :一直存在到得喝重新自举或显式的删除该对象为止。如SystemV 消息队列和共享内存区。 Posix消息队列和共享内存区。

3.随文件系统持续性的IPC :一直存在到显式的删除该对象为止。即使内存重新自举了,该对象还是保持其值。Posix消息队列和共享内存区。

进程同步:(司机-售票员)两个或多个进程需要相互配合才能完成一项任务

进程互斥:(卖票,提款等)由于各个进程都要访问共享资源,而且这些资源需要排他使用,因此各个进程间需要竞争使用这些资源,这种关系就叫进程互斥

司机售票员问题:

司机:

while(1)
{
    启动车辆;

    正常行驶;

    到站停车;
}
售票员:
while(1)
{
    关门;

    卖票;

    开门;
}

卖票:

售票机:

while(p > 0)                  //p为还有的票数
{
   p--;
}
信号量机制:(计数器)

PV操作提出者:迪杰斯特拉(Dijkstra)

信号量:

互斥:P操作和V操作在同一个进程中

同步:P操作和V操作在不同的进程中

信号量的结构体模型:

struct semaphore{
        int value;                               //资源数目
        struct task_struct *ptr;                 //等待该信号量,处于等待状态
};
信号量值的含义:

S > 0:表示S有这么多的资源可以使用

S = 0:表示没有资源可以使用,也没有进程在该信号量上等待资源

S < 0:表示有|S|个进程在等待该资源

P原语:
	p(s)
	{
		s.value--;			
		{
			将该进程只为等待状态
			将该进程的task_struct插入到相应的等待队列
		}
	}
V原语:
	v(s)
	{
		s.value++;
		if(s.value <= 0)
		{
			将等待队列上的进程唤醒(一般为队头进程)
			将其改为就绪状态
			放入就绪队列
		}
	}

PV原语表示司机售票员问题:


售票机:Sem(1)

while(1)

{

    P(Sem);

    if(p > 0)    p--;

    V(Sem);

}


死锁:是指两个或两个以上的进程(或线程)在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。

死锁发生的四个条件:
1、互斥条件:进程对资源的访问是排他性的,如果一个线程对占用了某资源,那么其他线程必须处于等待状态,直到资源被释放。
2、请求和保持条件:进程T1至少已经保持了一个资源R1占用,但又提出对另一个资源R2请求,而此时,资源R2被其他进程T2占用,于是该进程T1也必须等待,但又对自己保持的资源R1不释放。
3、不剥夺条件:进程已获得的资源,在未使用完之前,不能被其他进程剥夺,只能在使用完以后由自己释放。

4、环路等待条件:在死锁发生时,必然存在一个“进程-资源环形链”,即:{p0,p1,p2,...pn},进程p0(或线程)等待p1占用的资源,p1等待p2占用的资源,pn等待p0占用的资源。(最直观的理解是,p0等待p1占用的资源,而p1而在等待p0占用的资源,于是两个进程就相互等待)

预防死锁:

1.破坏请求保持条件。

1> 一次性分配给进程它在运行期间所需要的全部资源。缺点:造成资源的浪费

2> 允许一个进程只获得运行初期所需要的资源后,便开始运行,进程运行过程中再逐步释放已分配给自己的,并且已用毕的全部资源,然后请求新的所需要的资源。

2.破坏不可抢占条件。

当一个进程保持了某些不可被强占资源的进程,提出新的资源请求而不能被满足时,它必须释放已经保持得所有资源,待以后需要时再重新申请。也就是说已占有的资源被暂时的释放,或者说被抢占

3.破坏循环等待条件

规定每个进程必须按序请求资源

一般的死锁避免算法:(银行家算法)

银行家算法:

1.当顾客的资金需求小于银行家现有的资金总量,接纳该客户

2.顾客可以分期贷款,但贷款总额不能超过最大需求量

3.当银行家现有的资金不能满足顾客的需求,可以推迟支付,但总能在有限的时间内让顾客得到贷款

4.当顾客使用完全部贷款,一定能够在有限的时间内归还所有资金

哲学家就餐问题:典型的死锁问题

while(1)
{
	思考;
	if(饿)
	{
		拿左筷子;
		拿右筷子;

		吃;
		放左筷子;
		放右筷子;
	}
}

1. 为了克服死锁风险,可以再添加5根筷子,或者教会哲学家仅用一根筷子吃饭。

2. 另一种方法是添加一个服务员,他只允许4位哲学家同时进入餐厅,由于最多有四位哲学家就坐,则至少有一位哲学家拿到可两根筷子.


猜你喜欢

转载自blog.csdn.net/bian_cheng_ru_men/article/details/79963684