进程间通信与同步

进程之间的通信指数据突破进程空间的隔离,完成数据在进程间传递。

管道

进程间的管道通信方式有两种形式,无名管道用于父子进程间,命名管道可以用在任意进程间。

无名管道

管道是单向的信道,进程从管道的写端口写入数据,需要数据从读端口中获取数据,数据在管道中按到达顺序流动。
下面展示一个父子进程用无名管道通信的例子:
pipe()用两个文字描述符来指代管道通信的读端和写端(fsn[]数组)。其中父进程关闭了管道的读端fds【0】并往管道的写端fds【1】写出信息,子进程关闭了管道的写端fds[1]并从管道的读端fds[0]读回信息。
在这里插入图片描述在这里插入图片描述

命名管道:

前面提到的无名管道有一个主要缺点,只能通过父子进程之间(及其后代 )使用文件描述符的继承来访问,无法在任意的进程之间使用。命名管道 (named pipe)或者叫FIFO则突破了这个限制 。可以说FIFO就是无名管道的升级版—— 有可访问的磁盘索引节点,即FIFO文件将出现在目录树中(不像无名管道那样只存在于pipefs特殊文件系统中)。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在Linux中执行ipcs命令可以查看到当前系统中所有的System V IPC对象 ,如图所示。此时系统中还没有创建消息队列和信号量数组(或称信号量集), 有3段共享内存区。

在这里插入图片描述
查看这些IPC对象时还可以带上参数,ipcs-a是默认的输出全部信息、ipcs-m显示共享内存的信息 、ipcs -q显示消息队列的信息、ipcs -s显示信号量集的信息。另外用 还有一些格式控制的参数 ,–t将会输出带时间信息、-p将输出进程PID信息 、-c将输出创建者/拥有者 的PID、-l输出相关的限制条件。例如用ipcs -ql将显示消息队列的限制条件.

消息队列:

消息 队列有些像邮政中的邮箱,里面的消息有点像信件—— 有信封以及写有内容的信纸。由于各条消息可以通过类型(type)进行区分,因此可以用于多个进程间通信。比如一个任务分派进程 ,创建了若干个执行子进程,不管是父进程发送分派任务的消息,还是子进程发送任务执行的消息,都将type设置为目标进程的PID,目标进程只接收消息类型为type的消息就实现了子进程只接收自己的任务,父进程只接收任务结果。

在这里插入图片描述在这里插入图片描述在这里插入图片描述

POSXI信号量

p操作:down
v操作:up
p,v操作为原语操作

有名信号量

有名信号量由于可以通过标识来访问,因此可以同时用于进程间同步和线程间同步。下面我们来看看POSIX有名信号的使用过程和进程呈现出来的同步关系。有名 信号量的创建使用sem_open()完成 。

用pv操作解决进程间互斥问题:

  • 分析并发进程的关键活动,划定临界区
  • 设置信号量mutex,初值为1
  • 在临界区前实施P(mutex)
  • 在临界区之后实施V(mutex)
    在这里插入图片描述

用信号量解决生产者/消费者问题

  • List item
    在这里插入图片描述
    生产者要判断缓冲区是否有空位置,有空位置才能执行操作。生产者完成操作之后full++。
    消费者要判断缓冲区是否有满的缓冲区,有才进行操作。消费者完成操作之后empty++。
    生产者和消费者的操作不能同时进行,所以要在他们操作前加上一个互斥信号量。

在这里插入图片描述在这里插入图片描述

p操作不能颠倒,会造成死锁。而v操作可以颠倒顺序。

用信号量解决读者/写者问题

允许多个读者同时进行读操作
不允许多个写者同时操作
不允许读者,写着同时操作

第一类读写者问题:读者优先

需要注意,P(w)不需要每个读者都做,第一个读者做就够了,V(w)也不需要每个读者去做,最后一个读者去做就够了。
在这里插入图片描述
因为多读者问题对rc进行操作,所以对rc也要增加一个互斥信号量

在这里插入图片描述

用管程解决生产者消费者问题

hoare管程
管程是互斥进入的,所以当一个进程试图进入一个已被占用的管程时,应该在管程的入口处等待,为此,管程的入口处设置一个进程等待队列,称为入口等待队列。
如果进程P唤醒进程Q,则P等待Q执行。如果进程Q在执行中又唤醒进程R,则Q等待R执行…如此,在管城内部可能会出现多个等待进程。

在管程内部设置一个进程等待队列,称为紧急等待队列,紧急等待队列的优先级高于入口等待队列的优先级。
在这里插入图片描述

在这里插入图片描述
java中类似的管程线程wait和notify。

mesa管程:
signal->notify:
当一个正在管程中的进程执行notify(x)的操作时,它使得x条件队列得到通知,发信号的进程继续执行。
解决生产者消费者问题的时候,需要重新检测:(if改成while)

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/xqy3177563/article/details/89136647