进程间通信,学习一步到位

1、什么是进程?

答:进程是装入内存运行的程序段,是许多的系统对象拥有权的集合,换句大家经常引用的话说进程是资源分配的基本单位。

2、什么是线程?

答:线程是CPU运行调度的基本单位,线程必须被包含在进程中,一个进程可以有很多线程(至少有一个),这些线程共享进程的许多资源(如栈,寄存器)。

3、什么是进程通信?

浏览器向服务器发送请求获取资源就是一种靠套接字来进行的进程通信,这种通信通过一台主机的应用层端口以及Socket下发到运输层(TCP),再经过下面的网络层,数据链路层,物理层(这是计算机网络5层模型)传输到另一台机器的socket,最后服务器获取到该信息,实现进程间通信。

4、进程间通信机制(简称 IPC)可以分为消息传递,共享内存,同步。

Linux环境下,进程地址空间相互独立,每个进程各自有不同的用户地址空间。任何一个进程的全局变量在另一个进程中都看不到,所以进程和进程之间不能相互访问,要交换数据必须通过内核,在内核中开辟一块缓冲区,进程1把数据从用户空间拷到内核缓冲区,进程2再从内核缓冲区把数据读走,内核提供的这种机制称为进程间通信(IPC,InterProcess Communication)

  • 消息传递就包括:管道、FIFO命名管道、消息队列等
  • 共享内存:包括匿名、具名
  • 同步:包括互斥量、读写锁、信号量等。

共享内存与消息队列图示

在这里插入图片描述

什么是共享内存、管道?

  1. 共享内存其原理就是将一份物理内存映射到不同进程各自的虚拟地址空间,使每一个进程都可以读取这份数据,来实现通信,因为是直接通过内存操作,所以是一种非常高效的通信方式.
  2. 管道(Pipe)是一种具有两个端点的通信通道:有一端句柄的进程可以和有另一端句柄的进程通信。管道可以是单向-一端是只读的,另一端点是只写的;也可以是双向的一—管道的两端点既可读也可写。

进程属于内核的基本功能,所以不同的操作系统在实现进程通信有一定的区别

5、Windows下进程通信的方式:

  1. 文件映射:
    文件映射(Memory-Mapped Files)能使进程把文件内容当作进程地址区间一块内存那样来对待。因此,进程不必使用文件I/O操作(正常来说需要用输入输出流来读写文件ioStream),只需简单的指针操作就可读取和修改文件的内容;
    Win32API允许多个进程访问同一文件映射对象,各个进程在它自己的地址空间里接收内存的指针。通过使用这些指针,不同进程就可以读或修改文件的内容,实现了对文件中数据的共享。
    注意:文件映射是在多个进程间共享数据的非常有效方法,有较好的安全性。但文件映射只能用于本地机器的进程之间,不能用于网络中,而开发者还必须控制进程间的同步。
  2. 共享内存:
    Win32API中共享内存(SharedMemory)实际就是文件映射的一种特殊情况。进程在创建文件映射对象时用0xFFFFFFFF来代替文件句柄(HANDLE),就表示了对应的文件映射对象是从操作系统页面文件访问内存,其它进程打开该文件映射对象就可以访问该内存块
  3. 匿名管道:
    匿名管道(Anonymous Pipe)是在父进程和子进程之间,或同一父进程的两个子进程之间传输数据的无名字的单向管道。通常由父进程创建管道,然后由要通信的子进程继承通道的读端点句柄或写端点句柄,然后实现通信。父进程还可以建立两个或更多个继承匿名管道读和写句柄的子进程。这些子进程可以使用管道直接通信,不需要通过父进程。
  4. 命名管道(FIFO):先进先出的通信方式。
    命名管道(Named Pipe)是服务器进程和一个或多个客户进程之间通信的单向或双向管道。不同于匿名管道的是命名管道可以在不相关的进程之间和不同计算机之间使用,服务器建立命名管道时给它指定一个名字,任何进程都可以通过该名字打开管道的另一端,根据给定的权限和服务器进程通信。
  5. 动态链接库:
    DLL解释:与动态链接库连接的可执行文件只包含它需要的函数的引用表,而不是所有的函数代码,只有在程序执行时, 那些需要的函数代码才被拷贝到内存中,这样就使可执行文件比较小, 节省磁盘空间,操作系统使用虚拟内存,使得一份DLL驻留在内存中被多个程序使用,节省内存;Win32动态连接库(DLL)中的全局数据可以被调用DLL的所有进程共享,这就又给进程间通信开辟了一条新的途径,当然访问时要注意同步问题。
  6. 远程调用RPC
    Win32 API提供的远程过程调用(RPC)使应用程序可以使用远程调用函数,这使在网络上用RPC进行进程通信就像函数调用那样简单。RPC既可以在单机不同进程间使用也可以在网络中使用。
  7. Socket
    WindowsSockets规范是以U.C.Berkeley大学BSD UNIX中流行的Socket接口为范例定义的一套Windows下的网络编程接口。除了Berkeley Socket原有的库函数以外,还扩展了一组针对Windows的函数,使程序员可以充分利用Windows的消息机制进行编程。
  8. 剪贴板
    Windows剪贴板应该算是一种比较简单开销小的IPC,内置在windows并使用系统的内部资源RAM,或者虚拟内存类临时保存剪切和复制的信息,系统预留的一块全局共享内存,用来暂存在各进程间进行交换的数据:提供数据的进程创建一个全局内存块,并将要传送的数据移到或复制到该内存块;接受数据的进程(也可以是提供数据的进程本身)获取此内存块的句柄,并完成对该内存块数据的读取。这里有一点疑问,我认为剪贴板并不是把所有的信息复制到那个内存,而是把路径等信息存入再进行拷贝?
  9. WM_COPYDATA消息
    当一个应用向另一个应用传送数据时,发送方只需使用调用SendMessage函数,参数是目的窗口的句柄、传递数据的起始地址、WM_COPYDATA消息。接收方只需像处理其它消息那样处理WM_COPY DATA消息,这样收发双方就实现了数据共享。WM_COPYDATA消息无疑是一种经济实惠的一中方法 。

6、Linux下进程通信方式

  1. 管道:
    与上述windows的管道类似,也分为匿名与有名字的管道。管道可用于具有亲缘关系进程间(父子,兄弟进程)的通信,有名管道克服了管道没有名字的限制,允许不同无亲缘关系的进程通信
  2. 信号(signal):
    信号是比较复杂的通信方式,用于通知接受进程有某种事件发生,除了用于进程间通信外,进程还可以发送信号给进程本身;linux除了支持Unix早期信号语义函数sigal外,还支持语义符合Posix.1标准的信号函数sigaction
  3. 报文(Message)队列(消息队列):
    消息队列是消息的链接表,包括Posix消息队列system V消息队列。有足够权限的进程可以向队列中添加消息,被赋予读权限的进程则可以读走队列中的消息,注意消息队列是创建文件方式建立,所以即使添加消息的进程结束,保存在消息队列的消息也不会消失;消息队列克服了信号承载信息量少,管道只能承载无格式字节流以及缓冲区大小受限等缺点。
  4. 共享内存:
    上面描述了基本原理,往往与其它通信机制,如信号量结合使用,来达到进程间的同步及互斥。
  5. 信号量(semaphore):
    主要作为进程间以及同一进程不同线程之间的同步手段。(线程间通信业经常使用信号量)
    信号量是一个特殊的变量,只能对其进行初始化,PV以及删除操作(这里涉及到同步与锁的一些内容,可以查一下)。
  6. 套接字(Socket)

对几种IPC的简单比较:

  1. 管道,速度较慢,缓冲区大小受限,只能承载无格式的字节流。只能用于有亲缘关系的进程。(无名管道:只存在于内存中的文件;命名管道:存在于实际的磁盘介质或者文件系统)
  2. FIFO管道,任何进程间都可以通信,包括不同机器上的管道,速度较慢。
  3. 消息队列:因为位于内核中,所以容量受限,第一次读取时要注意上次添加的消息是否读取。
  4. 信号量:不能传递复杂的消息,只用于同步信息。
  5. 共享内存:能很容易的控制变量,速度快,要注意读写安全性,避免死锁等。

7、共享内存和消息队列原理详解

进程间通信(IPC):共享内存和消息队列原理详解

8、匿名管道和命名管道总结

1、管道是特殊类型的文件,在满足先入先出的原则条件下可以进行读写,但不能进行定位读写。
2、匿名管道是单向的,只能在有亲缘关系的进程间通信;有名管道以磁盘文件的方式存在,可以实现本机任意两个进程通信。
3、、无名管道阻塞问题:无名管道无需显示打开,创建时直接返回文件描述符,在读写时需要确定对方的存在,否则将退出。如果当前进程向无名管道的一端写数据,必须确定另一端有某一进程。如果写入无名管道的数据超过其最大值,写操作将阻塞,如果管道中没有数据,读操作将阻塞,如果管道发现另一端断开,将自动退出。
4、命名管道阻塞问题:命名管道在打开时需要确实对方的存在,否则将阻塞。即以读方式打开某管道,在此之前必须一个进程以写方式打开管道,否则阻塞。此外,可以以读写(O_RDWR)模式打开命名管道,即当前进程读,当前进程写,不会阻塞。

9、消息队列特点总结

1、消息队列是消息的链表,具有特定的格式,存放在内存中并由消息队列标识符标识.
2、消息队列允许一个或多个进程向它写入与读取消息
3、管道和消息队列的通信数据都是先进先出的原则。
4、消息队列可以实现消息的随机查询,消息不一定要以先进先出的次序读取,也可以按消息的类型读取.比FIFO更有优势。
5、消息队列克服了信号承载信息量少,管道只能承载无格式字 节流以及缓冲区大小受限等缺。
6、目前主要有两种类型的消息队列:POSIX消息队列以及System V消息队列,System V消息队列目前被大量使用。System V消息队列是随内核持续的,只有在内核重起或者人工删除时,该消息队列才会被删除。

10、 加鸡腿🍗

信号量(SIGNAL)

  • 信号是Linux系统中用于进程间互相通信或者操作的一种机制,信号可以在任何时候发给某一进程,而无需知道该进程的状态。
  • 如果该进程当前并未处于执行状态,则该信号就有内核保存起来,直到该进程回复执行并传递给它为止。
  • 如果一个信号被进程设置为阻塞,则该信号的传递被延迟,直到其阻塞被取消是才被传递给进程。

Linux系统中常用信号:
1、SIGHUP:用户从终端注销,所有已启动进程都将收到该进程。系统缺省状态下对该信号的处理是终止进程。
2、SIGINT:程序终止信号。程序运行过程中,按Ctrl+C键将产生该信号。
3、SIGQUIT:程序退出信号。程序运行过程中,按Ctrl+\键将产生该信号。
4、SIGBUS和SIGSEGV:进程访问非法地址。
5、SIGFPE:运算中出现致命错误,如除零操作、数据溢出等。
6、SIGKILL:用户终止进程执行信号。shell下执行kill -9发送该信号。
7、SIGTERM:结束进程信号。shell下执行kill 进程pid发送该信号。
8、SIGALRM:定时器信号。
9、SIGCLD:子进程退出信号。如果其父进程没有忽略该信号也没有处理该信号,则子进程退出后将形成僵尸进程。
可以使用 kill -l 查看当前系统可用信号有哪些

信号生命周期和处理流程

  1. 信号被某个进程产生,并设置此信号传递的对象(一般为对应进程的pid),然后传递给操作系统;
  2. 操作系统根据接收进程的设置(是否阻塞)而选择性的发送给接收者,如果接收者阻塞该信号(且该信号是可以阻塞的),操作系统将暂时保留该信号,而不传递,直到该进程解除了对此信号的阻塞(如果对应进程已经退出,则丢弃此信号),如果对应进程没有阻塞,操作系统将传递此信号。
  3. 目的进程接收到此信号后,将根据当前进程对此信号设置的预处理方式,暂时终止当前代码的执行,保护上下文(主要包括临时寄存器数据,当前程序位置以及当前CPU的状态)、转而执行中断服务程序,执行完成后在回复到中断的位置。当然,对于抢占式内核,在中断返回时还将引发新的调度。

11、进程通信的两种应用方式

  1. 本地过程调用
    本地过程调用(LPC)LPC用在多任务操作系统中,使得同时运行的任务能互相会话。这些任务共享内存空间使任务同步和互相发送信息。
  2. 远程过程调用
    远程过程调用(RPC)RPC类似于LPC,只是在网上工作。RPC开始是出现在Sun微系统公司和HP公司的运行UNⅨ操作系统的计算机中。
  3. 远程过程调用图解
    在这里插入图片描述
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值