linux网络编程之进程间通信介绍

时间:2022-02-18 05:10:50

从今天起,开始学习进程间通信相关的东东,关于socket的编程先告一段落了,在学习进程间通信之前,首先先要了解一些概念,所以,这次不开始真正的代码编写,先纯理论,理解了为之后的更深入的学习可以打下良好的基础,下面进入正题:

linux网络编程之进程间通信介绍

实际上这也是进程之间的两种关系,在学习这两种关系之前,需要回顾一下顺序程序与并发程序的特征

顺序程序特征:

①、顺序性

顺序程序执行的顺序是按照指令的先后顺序来执行的,当前的指令需依赖于前一条指令,并与前一条指令构成了一定的因果关系,后一条指令的执行一定要在前一条指令的基础之上才能够运行。

②、封闭性:(运行环境的封闭性)

也就是说顺序程序在运行过程中,它的运行环境不会受其它程序的影响。

③、确定性

只要给程序一定的输入,不管程序是运行在比较快的机器上,还是运行在比较慢的机器上,它一定会有特定的输出。

④、可再现性

一个程序在一定时期运行的结果,跟另外一个时期运行的结果可以是一样的,只要是具有相同的输入,就一定具有相同的输出,这跟"确定性"是很有关系。

并发程序特征【就没有以上顺序程序的特征了】:

①、共享性

②、并发性

③、随机性

【说明】:关于以上的特征只需了解既可。

 下面来正式理解进程同步与进程互斥:

linux网络编程之进程间通信介绍

linux网络编程之进程间通信介绍 

如两个小孩争抢同一个玩具,这是一种互斥关系。

 

linux网络编程之进程间通信介绍

linux网络编程之进程间通信介绍 

下面来举一个同步的示例:汽车售票

linux网络编程之进程间通信介绍

通常情况下,将这两种关系统称为同步关系。

linux网络编程之进程间通信介绍

①、数据传输:一个进程需要将它的数据发送给另一个进程

②、资源共享:多个进程之间共享同样的资源。

③、通知事件:一个进程需要向另一个或一组进程发送消息,通知它(它们)发生了某种事件(如进程终止时要通知父进程)。【如:上面说的汽车售票的例子】

④、进程控制:有些进程希望完全控制另一个进程的执行(如Debug进程),此时控制进程希望能够拦截另一个进程的所有陷入和异常,并能够及时知道它的状态改变。【可以通过信号的方式来实现,如:SIGTRAP信号】

linux网络编程之进程间通信介绍 

①、管道

其中匿名管道可以用于亲缘关系的进程之间进行通信,而有名管道可以用于不相关的进程之间进行通信。

②、System V进程间通信【使用最广泛】

这个是之后发展出来的,之后还会介绍。

③、POSIX进程间通信

linux网络编程之进程间通信介绍

①、文件

这个其实也是进程间通信的一种试,一个进程向一个文件写数据,而另外一个进程向一个文件读数据。

②、文件锁:是为了互斥和同步用的

③、管道(pipe)和有名管理(FIFO)

④、信号(signal)

⑤、消息队列

⑥、共享内存

⑦、信号量

其中System V包含:消息队列、共享内存、信号量

⑧、互斥量

⑨、条件变量

⑩、读写锁

⑪、套接字(socket)

下面来介绍一下System V IPC & POSIX IPC:

linux网络编程之进程间通信介绍

linux网络编程之进程间通信介绍

linux网络编程之进程间通信介绍

由于这三种共享方式,就出现了三种进程间通信对象的持续性,如下:

linux网络编程之进程间通信介绍

①、随进程持续:一直存在直到打开的最后一个进程结束。(如pipe和FIFO)

②、随内核持续:一直存在直到内核自举或显式删除(如System V消息队列、共享内存、信号量)

③、随文件系统持续:一直存在直到显式删除,即使内核自举还存在。(POSIX消息队列、共享内存、信号量如果是使用映射文件来实现)

【说明】:IPC(Inter-Process Communication,进程间通信

linux网络编程之进程间通信介绍

在上面已经介绍了进程的两种关系:互斥和同步,死锁则是进程的另外一种关系:

死锁是指多个进程之间相互等待对方的资源,而在得到对方资源之前又不释放自己的资源,这样,造成循环等待的一种现象。如果所有进程都在等待一个不可能发生的事,则进程就死锁了。

linux网络编程之进程间通信介绍

linux网络编程之进程间通信介绍

linux网络编程之进程间通信介绍

linux网络编程之进程间通信介绍

linux网络编程之进程间通信介绍

linux网络编程之进程间通信介绍

①、资源一次性分配:(破坏请求和保持条件)

②、可剥夺资源:破坏不可剥夺条件)

③、资源有序分配法:(破坏循环等待条件)

linux网络编程之进程间通信介绍

①、预防死锁的几种策略,会严重地损害系统性能。因此在避免死锁时,要施加较弱的限制,从而获得较满意的系统性能。

②、由于在避免死锁的策略中,允许进程动态地申请资源。因而,系统在进行资源分配之前预先计算资源分配的安全性。若此次分配不会导致系统进入不安全状态,则将资源分配给进程;否则,进程等待。

下面来对死锁进行举例,其中最具有代表性的避免死锁算法是银行家算法

为保证资金的安全,银行家规定:

(1) 当一个顾客对资金的最大需求量不超过银行家现有的资金时就可接纳该顾客; 

(2) 顾客可以分期贷款,但贷款的总数不能超过最大需求量

(3) 当银行家现有的资金不能满足顾客尚需的贷款数额时,对顾客的贷款可推迟支付,但总能使顾客在有限的时间里得到贷款

(4) 当顾客得到所需的全部资金后,一定能在有限的时间里归还所有的资金. 

另外还有一个很经典的例子:哲学家就餐问题

1965年,Dijkstra(迪杰斯特拉)提出并解决了一个他称之为哲学家就餐的同步问题。从那时起,每个发明新的同步原语的人都希望通过解决哲学家就餐问题来展示其同步原语的精妙之处。这个问题可以简单地描述如下:五个哲学家围坐在一张圆桌周围,每个哲学家面前都有一盘通心粉。由于通心粉很滑,所以需要两把叉子才能夹住。相邻两个盘子之间放有一把叉子,餐桌如图2-44所示。

linux网络编程之进程间通信介绍

哲学家的生活中有两种交替活动时段:即吃饭和思考(这只是一种抽象,即对哲学家而言其他活动都无关紧要)。当一个哲学家觉得饿了时,他就试图分两次去取其左边和右边的叉子,每次拿一把,但不分次序。如果成功地得到了两把叉子,就开始吃饭,吃完后放下叉子继续思考。关键问题是:能为每一个哲学家写一段描述其行为的程序,且决不会死锁吗?(要求拿两把叉子是人为规定的,我们也可以将意大利面条换成中国菜,用米饭代替通心粉,用筷子代替叉子。)

哲学家就餐问题解法:

①、服务生解法

哲学家在拿刀叉之前,需要得到服务生的同意,也就是服务生是管理者,他在统一的分配刀叉,他在判定当前的资源是否处于一个安全的状态,如果资源处于一个安全的状态,服务生就允许哲学家将叉子拿起,否则就不允许。

②、最多4个哲学家

这不是解决问题的最好方案,因为将我们的限定条件更改了,4个哲学家有5把叉子势必有一个哲学家能得到两把叉子,这实际上就是一种抽屉原则。

③、仅当一个哲学家两边叉子都可用时才允许他拿叉子

④、给所有哲学家编号,奇数号的哲学家必须首先拿左边的筷子,偶数号的哲学家则反之

linux网络编程之进程间通信介绍

信号量和P、V原语由Dijkstra(迪杰斯特拉)提出,其中他有很多贡献:

①、在程序设计中,提出了goto语句是有害的,所以可以认为他是程序设计语言之父。

②、在操作系统,提出了信号量、PV原语。

③、在网络上,提出了最短路径。

linux网络编程之进程间通信介绍

linux网络编程之进程间通信介绍

linux网络编程之进程间通信介绍

linux网络编程之进程间通信介绍

linux网络编程之进程间通信介绍

根据上面的描述,很容易得到信号量它所拥有的数据结构,如下:

linux网络编程之进程间通信介绍

另外还可以得出PV原语的伪代码:

linux网络编程之进程间通信介绍

 linux网络编程之进程间通信介绍

linux网络编程之进程间通信介绍

linux网络编程之进程间通信介绍

用PV原语主要是来解决进程的同步互斥的问题,所以,下面举例来说明:

linux网络编程之进程间通信介绍

 linux网络编程之进程间通信介绍

linux网络编程之进程间通信介绍

linux网络编程之进程间通信介绍

linux网络编程之进程间通信介绍

linux网络编程之进程间通信介绍

linux网络编程之进程间通信介绍

linux网络编程之进程间通信介绍

linux网络编程之进程间通信介绍

linux网络编程之进程间通信介绍

有一汽车租赁公司有两部敞篷车可以出租,假定同时来了四个顾客都要租敞篷车,那么肯定会有两个人租不到:

linux网络编程之进程间通信介绍

用一个简单的图来描述一下:

linux网络编程之进程间通信介绍

linux网络编程之进程间通信介绍

另外需要注意:必须是同类的资源才能够进行PV操作,如果一部是敞篷车,一部是普通的汽车,是不能够进行PV来解决同步问题的。

相关概念先学到这,完全是纯概念的,可能会比较抽象,但是了解了这些概念之后为之后的编码会打下良好的基础,下次就会用代码来进行验证了,下回见~~~