进程间通信(IPC)

一个过程可以有两种类型:

null
  • 独立程序。
  • 合作过程。

独立流程不受其他流程执行的影响,而协作流程可能受其他执行流程的影响。虽然人们可以认为那些独立运行的进程将非常高效地执行,但在现实中,有许多情况下,可以利用协作性来提高计算速度、便利性和模块化。进程间通信(IPC)是一种允许进程相互通信并同步其操作的机制。这些过程之间的沟通可以看作是它们之间合作的一种方法。流程可以通过以下两种方式相互通信:

  1. 共享内存
  2. 消息传递

下面的图1显示了进程之间通过共享内存方法和消息传递方法进行通信的基本结构。

操作系统可以实现这两种通信方法。首先,我们将讨论通信和消息传递的共享内存方法。使用共享内存的进程之间的通信需要进程共享一些变量,这完全取决于程序员将如何实现它。可以这样设想使用共享内存的一种通信方式:假设process1和process2同时执行,它们共享一些资源或使用另一个进程的一些信息。Process1生成有关正在使用的某些计算或资源的信息,并将其作为记录保存在共享内存中。当process2需要使用共享信息时,它将检入存储在共享内存中的记录,并记录process1生成的信息,并相应地采取行动。进程可以使用共享内存从另一个进程中提取信息作为记录,并将任何特定信息传递给其他进程。 让我们讨论一个使用共享内存方法在进程之间进行通信的示例。

图片[1]-进程间通信(IPC)-yiteyi-C++库

i) 共享内存方法

例:生产者消费者问题 有两个过程:生产者和消费者。生产者生产某些商品,消费者消费该商品。这两个进程共享一个称为缓冲区的公共空间或内存位置,生产商生产的商品在缓冲区中存储,消费者在需要时从缓冲区消费商品。这个问题有两个版本:第一个版本称为无界缓冲区问题,其中生产者可以继续生产商品,并且缓冲区的大小没有限制;第二个版本称为有界缓冲区问题,其中生产者可以在开始等待消费者消费商品之前生产一定数量的商品。我们将讨论有界缓冲区问题。首先,生产者和消费者将共享一些共同的记忆,然后生产者将开始生产商品。如果生产的商品总数等于缓冲区的大小,生产者将等待消费者消费它。同样,消费者将首先检查商品的可用性。如果没有产品,消费者将等待生产商生产。如果有可用的物品,消费者将消费它们。下面提供了要演示的伪代码: 两个进程之间共享数据

C

#define buff_max 25
#define mod %
struct item{
// different member of the produced data
// or consumed data
---------
}
// An array is needed for holding the items.
// This is the shared place which will be
// access by both process
// item shared_buff [ buff_max ];
// Two variables which will keep track of
// the indexes of the items produced by producer
// and consumer The free index points to
// the next free index. The full index points to
// the first full index.
int free_index = 0;
int full_index = 0;


生产者过程代码

C

item nextProduced;
while (1){
// check if there is no space
// for production.
// if so keep waiting.
while ((free_index+1) mod buff_max == full_index);
shared_buff[free_index] = nextProduced;
free_index = (free_index + 1) mod buff_max;
}


消费者过程代码

C

item nextConsumed;
while (1){
// check if there is an available
// item  for consumption.
// if not keep on waiting for
// get them produced.
while ((free_index == full_index);
nextConsumed = shared_buff[full_index];
full_index = (full_index + 1) mod buff_max;
}


在上面的代码中,当(free_index+1)mod buff max空闲时,生产者将再次开始生产,因为如果它不空闲,这意味着消费者仍然可以消费一些物品,因此不需要生产更多。同样,如果自由索引和完整索引指向同一个索引,这意味着没有可消费的项目。

ii)消息传递方法

现在,我们将开始讨论进程之间通过消息传递进行的通信。在这种方法中,进程相互通信而不使用任何类型的共享内存。如果两个过程p1和p2想要彼此通信,它们将按如下方式进行:

  • 建立通信链路(如果链路已经存在,则无需再次建立。)
  • 开始使用基本原语交换消息。 我们至少需要两个原语: – 邮寄 (信息、目的地)或 邮寄 (留言) – 接收 (消息、主机)或 接收 (留言)

图片[2]-进程间通信(IPC)-yiteyi-C++库

消息大小可以是固定大小,也可以是可变大小。如果它是固定大小的,那么对于操作系统设计师来说很容易,但是对于程序员来说很复杂;如果它是可变大小的,那么对于程序员来说很容易,但是对于操作系统设计师来说很复杂。标准消息可以由两部分组成: 头部和身体。 这个 标题部分 用于存储消息类型、目标id、源id、消息长度和控制信息。控制信息包含缓冲区空间、序列号、优先级等信息。通常,消息是使用FIFO方式发送的。

通过通信链路传递的消息。 直接和间接通信链路 现在,我们将开始讨论实现通信链接的方法。在实施链接时,需要记住以下问题:

  1. 如何建立联系?
  2. 链接是否可以与两个以上的进程关联?
  3. 每对通信进程之间可以有多少个链接?
  4. 链路的容量是多少?链接可以容纳的消息大小是固定的还是可变的?
  5. 链接是单向的还是双向的?

链路具有一定的容量,它决定了可以临时驻留在其中的消息的数量,对于这些消息,每个链路都有一个与其相关联的队列,该队列可以是零容量、有界容量或无界容量。在零容量情况下,发送方等待,直到接收方通知发送方它已收到消息。在非零容量的情况下,进程不知道在发送操作之后是否收到了消息。为此,发送方必须明确地与接收方通信。链路的实现取决于具体情况,它可以是直接通信链路,也可以是定向通信链路。 直接通信链路 当流程使用特定的流程标识符进行通信,但很难提前识别发送者时,就会实现。 例如打印服务器。 直接沟通 通过共享邮箱(端口)完成,该邮箱由一个消息队列组成。发送方将邮件保存在邮箱中,接收方将其接收。

通过交换消息传递的消息。

同步和异步消息传递: 被阻止的进程是指等待某个事件的进程,例如资源可用或I/O操作完成。IPC可以在同一台计算机上的进程之间进行,也可以在不同计算机上运行的进程之间进行,即在网络化/分布式系统中。在这两种情况下,在发送消息或试图接收消息时,进程可能会被阻塞,也可能不会被阻塞,因此消息传递可能是阻塞的,也可能是非阻塞的。考虑了阻塞 同步的 阻止发送 表示在接收方收到消息之前,发送方将被阻止。同样地, 阻止接收 在消息可用之前,接收器将一直处于阻塞状态。考虑非阻塞 异步的 非阻塞发送让发送方发送消息并继续。类似地,非阻塞接收让接收方接收有效消息或null。经过仔细分析,我们可以得出结论,对于发送方来说,在消息传递后不阻塞是更自然的,因为可能需要将消息发送到不同的进程。但是,如果发送失败,发送方希望接收方确认。类似地,由于来自接收到的消息的信息可用于进一步的执行,因此接收器在发出receive之后阻塞是更自然的。同时,如果消息发送继续失败,接收方将不得不无限期等待。这就是为什么我们也会考虑其他信息传递的可能性。基本上有三种首选组合:

  • 阻止发送和阻止接收
  • 非阻塞发送和非阻塞接收
  • 非阻塞发送和阻塞接收(主要使用)

在直接消息传递中 ,希望通信的流程必须明确指定通信的收件人或发件人。 例如 发送(p1,消息) 意思是将信息发送给p1。 同样地, 接收(p2,消息) 表示从p2接收消息。 在这种通信方法中,自动建立通信链路,通信链路可以是单向的,也可以是双向的,但一对发送方和接收方之间可以使用一条链路,并且一对发送方和接收方不应拥有超过一对链路。发送和接收之间的对称性和不对称性也可以实现,也就是说,两个进程都将为发送和接收消息相互命名,或者只有发送方将为发送消息命名接收方,接收方无需为接收消息命名发送方。这种通信方法的问题是,如果一个进程的名称发生变化,这种方法将不起作用。 在间接信息传递中 ,进程使用邮箱(也称为端口)发送和接收消息。每个邮箱都有一个唯一的id,进程只有在共享一个邮箱时才能通信。只有当进程共享一个公共邮箱且单个链接可以与多个进程关联时,才能建立链接。每对进程可以共享多个通信链路,这些链路可以是单向的,也可以是双向的。假设两个进程希望通过间接消息传递进行通信,所需的操作是:创建邮箱,使用此邮箱发送和接收消息,然后销毁邮箱。使用的标准原语包括: 发送(消息) 这意味着将邮件发送到邮箱A。用于接收邮件的原语也以相同的方式工作,例如。 收到(一条、一条信息) 。此邮箱实现存在问题。假设有两个以上的进程共享同一个邮箱,并且假设进程p1向邮箱发送消息,哪个进程将成为接收方?这可以通过强制执行只有两个进程可以共享一个邮箱,或者强制执行在给定时间只有一个进程可以执行接收,或者随机选择任何进程并通知发送方有关接收方的信息来解决。邮箱可以对单个发送方/接收方对进行私有化,也可以在多个发送方/接收方对之间共享。端口是这种邮箱的一种实现,可以有多个发送方和一个接收方。它用于客户机/服务器应用程序(在这种情况下,服务器是接收器)。端口由接收进程所有,并由OS根据接收进程的请求创建,当接收进程终止自身时,可根据同一接收处理器的请求销毁端口。强制只允许一个进程执行接收可以使用互斥的概念来实现。 互斥邮箱 已创建,由n进程共享。发送方是非阻塞的,发送消息。执行接收的第一个进程将进入关键部分,所有其他进程将被阻塞并等待。 现在,让我们使用消息传递概念来讨论生产者-消费者问题。生产者在邮箱中放置项目(邮件内部),消费者可以在邮箱中至少存在一条邮件时使用项目。代码如下: 生产者代码

C

void Producer( void ){
int item;
Message m;
while (1){
receive(Consumer, &m);
item = produce();
build_message(&m , item ) ;
send(Consumer, &m);
}
}


消费者代码

C

void Consumer( void ){
int item;
Message m;
while (1){
receive(Producer, &m);
item = extracted_item();
send(Producer, &m);
consume_item(item);
}
}


IPC系统示例

  1. Posix:使用共享内存方法。
  2. 马赫:使用消息传递
  3. Windows XP:使用本地过程调用进行消息传递

客户机/服务器体系结构中的通信: 有多种机制:

  • 插座
  • 远程过程调用(RPC)

以上三种方法将在后面的文章中讨论,因为它们都是概念性的,值得单独发表文章。 参考资料:

  1. Galvin等人的操作系统概念。
  2. 巴里兰大学阿里尔·J·弗兰克讲座笔记/ppt

更多参考: http://nptel.ac.in/courses/106108101/pdf/Lecture_Notes/Mod%207_LN.pdf https://www.youtube.com/watch?v=lcRqHwIn5Dk 本文由 德格什·潘迪 。如果您发现任何不正确的地方,或者您想分享有关上述主题的更多信息,请发表评论。如果你喜欢Geeksforgek,并想贡献自己的力量,你也可以写一篇文章,然后把你的文章发到contribute@geeksforgeeks.org.看到你的文章出现在Geeksforgeks主页上,并帮助其他极客。

© 版权声明
THE END
喜欢就支持一下吧
点赞7 分享