进程间通信汇总笔记

1.信号(signal)      2.管道(pipe/fifo)     3.信号量(semophore)    4.消息队列(message queue)     5.共享内存(shared memory)    6.套接字(socket)

信号

操作系统给进程发送信号,本质上是给进程的PCB中写入数据,修改相应的PCB字段,进程在合适的时间去处理所接受的信号。我们模拟一下这样的场景:

1)用户输入一个命令,在shell下启动一个前台进程。

2)用户按下Ctrl-C,通过键盘输入产生了一个硬件中断。

3)如果CPU当前正在运行此进程的代码,则该进程的用户空间代码暂停执行,CPU从用户态切换到内核态处理中断。

4)终端驱动程序将Ctrl-C解释为一个SIGINT信号,记在该进程的PCB中。

5)当某个时刻从内核返回该进程的用户空间代码继续执行之前,首先处理PCB中记录的信号。SIGINT信号默认处理动作为终止信号,所以直接终止进程而不再返回到它的用户空间代码。


Ctrl-C所产生的信号只能发送给前台进程,如果想让其在后台运行,需要在命令后面加上&。这样shell不必等待进程结束就可以接受新的命令,启动新的进程。

进程间通信:管道(匿名与命名)篇

匿名管道之所以可以通信的本质在于,父进程fork子进程,父子进程各自拥有一个文件描述符表,但是两者的内容是一样的,既然内容一致,那么指向的就是同一个管道,即父子进程看到了同一份公共资源。

使用管道是有一些限制的,两个进程通过一个管道只能实现单向通信。比如上述例子,父进程写,子进程读,如果需要子进程写父进程读,就必须另开一个管道。

[匿名管道的5大特性]

①匿名管道只能单向通信。

②管道只能进行有血缘关系的进程间通信,通常用于父子进程。

③管道通信依赖于文件系统,即管道的生命周期随进程。

④管道的通信被称为面向字节流,与通信格式没有关系。

⑤自带同步机制,保证读写顺序一致。

命名管道(FIFO)

[本质]:命名管道在某种程度上可以看做是匿名管道 ,但他打破了匿名管道只能在有血缘关系的进程间的通信。命名管道之所以可以实现进程间通信在于通过同一个路径名而看到同一份资源,这份资源以FIFO的文件形式存在于文件系统中。

值得注意的是,FIFO总是按照先入先出的原则工作,第一个被写入的数据将首先从管道读出。

#include <sys/types.h>

#include <sys/stat.h>

int mkfifo(const char* filename,mode_t mode);

int mknod(const char* filename,mode_t mode | S_IFIFO,(dev_t)0);

1.信号:(signal)是一种处理异步事件的方式。信号时比较复杂的通信方式,用于通知接受进程有某种事件发生,除了用于进程外,还可以发送信号给进程本身。

2.信号量:(Semaphore)进程间通信处理同步互斥的机制。是在多线程环境下使用的一种设施, 它负责协调各个线程, 以保证它们能够正确、合理的使用公共资源。

信号量(Semaphore)______PV操作

同步与互斥

为了防止多个进程同时访问一块各项资源而引发的一系列问题,我们需要一种可以通过它生成并使用令牌来授权,在任意时刻只能有一个执行线程访问代码的临界区。而信号量则提供了这样的机制让一个临界区同一时间只有一个线程在访问,即信号量是用来协调进程对资源的访问的。

信号量在本质上是一种数据操作锁(计数器,记录统计临界资源的数目)。它本身不具备数据交换的功能,而是通过保护其他的通信(文件、外部设备)等临界资源来实现进程间通信。信号量在此过程中负责数据操作的互斥、同步等功能。

当请求一个使用信号量来表示的资源时,进程需要先读取信号量的值来判断资源是否可用:

①信号量 > 0:表示资源可用请求。

②信号量 = 0:无资源可用,进程会进入睡眠状态直至资源可用。

[生命周期]:信号量的生命周期与消息队列一样,不随进程的结束而结束,而是随内核的。

信号量的工作原理

由于信号量只能进行两种操作等待和发送信号,即P(sv)和V(sv),sv为信号量,它们的行为如下:

P(sv):如果sv的值大于零,就对其减1;如果它的值为零,就挂起该进程的执行。

V(sv):如果有其他进程因等待sv而被挂起,就让它恢复运行;如果没有进程因等待sv而挂起,就给它加1。

猜你喜欢

转载自blog.csdn.net/weixin_41143631/article/details/88671613
今日推荐