前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >进程通信

进程通信

原创
作者头像
ruochen
发布2021-12-05 22:30:31
1.1K0
发布2021-12-05 22:30:31
举报
文章被收录于专栏:若尘的技术专栏

相同: 都在 缓存内核读写先进先出 ,不支持 lseek 之类文件定位操作

1、匿名管道

$ ps auxf | grep mysql 用完就销毁| 就是一个 管道 ,将前一个命令(ps auxf)输出,作为后一命令(grep mysql)输入, 管道传数据是单向,如相互通信,要两个

2、命名管道 FIFO

$ mkfifo myPipe(名) 用前要mkfifo 命令创建,指定管道名,数据先进先出1) 基于“Linux一切皆文件”,管道也 文件 ,ls 看, 文件类型是 p ,就是 pipe(管道) 意思

2)往 myPipe 写入数据: 因为内容没被读,只有读后,命令才正常退出

3)读出 了,echo 命令正常退出

3、创建原理

1)匿名管道 创建, 通过 int pipe(intfd2) 系统调用:两个描述符:管道 读取端 fd0写入端 fd1 。ps:匿名管道是 特殊文件 ,只在 内存不存文件系统

2)管道,就是内核里一串缓存 。读写都在缓存内核中, 传数据无格式的流大小受限

3)跨进程通信实现: fork 创建子进程, 复制父进程文件描述符 ,两个进程各有两个「 fd0 与 fd1」,通过各自fd

读写同一管道文件

4)避免混乱:父进程 :关读 fd0,保留写fd1 子进程:关写 d1,保留读fd0所以, 双向通信,应两个管道

5)到这里,仅解析父子进程通信, 但shell 里面并不是这样

shell 里:执行 A | B命令时,都是 shell 创建的子进程, 不存父子关系,父进程都是 shell

ps:shell 里能使用一个管道搞定的事情,就不要多用一个管道,减少创建子进程开销

二、消息队列

解决频繁地交换数据问题, 内核中的消息链表

1、发时 ,分成一个个消息体(数据块),用户自 定义数据类型,固定大小 ,不像 管道无格式字节流数据

读后 ,内核 删除 消息体

2、生命周期:随内核 ,没有 释放 消息队列或没 关闭操作系统管道 随进程 结束销毁

3、不足:通信不及时,大小限制用户态内核态数据拷贝开销:写数据内核队列时 ,从用户态拷到内核态过程, 读同理 ,从内核到用户

不适合大数据传输 ,消息体、队列总长都有限制。Linux 内核中有MSGMAX 和 MSGMNB 消息和队列最大长,字节为单位

三、共享内存

解决 用户态与内核间的 消息拷贝

1、内存管理: 进程有自己独立的 虚拟内存空间不同进程虚拟内存 映射到 不同物理内存 中。即使进程 A

B 虚拟地址一样,其实访问的是不同的物理内存地址,对于数据的增删查改互不影响。

2、共享内存 机制 :就是拿出一块虚拟地址空间来,映射到相同的物理内存中 。这样写入,另一进程马上能看到,

不需拷贝,传来传去,提高通信速度

四、信号量

共享内存问题,同时修改同一共享内存,冲突。 信号量解决

信号量:整型计数器, 表示资源的数量,实现进程 间互斥与同步, 而不是用于缓存进程间通信数据

1、控制信号量两种原子操作:

1)P 操作 ,减 -1,减后: < 0被占用 ,进程阻塞等待; > = 0可用,继续执行

2)V 操作 ,加 1, <= 0,有阻塞唤醒运行; > 0,没有阻塞P 在进入共享资源之 V 离开 成对出现

2、例:两进程互斥访问共享内存,初始化信号量1

先P 操作,信号量变 0,可用,访问共享内存此时B 也访问, P 操作, -1被阻塞。A 完V 操作,恢复为 0,唤醒阻塞中B,B 完成执行 V,恢复1

例2,A 负责生产数据,B 是负责读,有顺序。初始化信号量可为 0

五、信号

上面都是常规工作模式。 异常用「信号」通知进程, 唯一异步通信机制。 ps: 跟信号量虽然名字相似,用途完全不一样

1、Linux 操作系统, 为响应各种各样事件,提供几十种信号, kill -l 命令,查看所有

2、 给进程发送信号终端 输入组合键: Ctrl+C 产生 SIGINT 信号,终止进程;Ctrl+Z 产生 SIGTSTP 信号, 停止进程,未结束

如果进程在后台运行,用kill+PID 号 kill -9 1050 ,立即结束

3、进程对信号处理方式

1)执行默认操作: Linux 对每种信号规定默认操作,SIGTERM 信号,终止。 Core Dump ,终止进程后,通过CoreDump 将当前进程的 运行状态保存在文件里 ,方便事后分析

2.捕捉信号: 定义信号处理函数。信号发生,执行相应函数

3.忽略信号 。不做任何处理。SIGKILL 和 SEGSTOP无法捕捉和忽略,用于任何时候中断或结束某一进程。

六、Socket

跨网络不同主机 上进程间通信(也可同主机) ,要 Socket

1、创建 socket 系统调用int socket(int domain,int type, int protocal)

domain:协议族 ,如 AF_INET 用于 IPV4、AF_INET6 用于 IPV6、AF_LOCAL/AF_UNIX 用于本机;

type :通信特性 ,如 SOCK_STREAM 表示字节流,对应 TCP、SOCK_DGRAM 表示数据报,对应 UDP、SOCK_RAW表示原始套接字;protocal (基本废弃):写成 0 即可,原本是用来指定通信协议的,通过前两个完成

2、不同socket 类型,通信方式不同

实现 TCP 字节流 通信:socket 是 AF_INET 和 SOCK_STREAM;

实现 UDP 数据报 通信:socket 是 AF_INET 和 SOCK_DGRAM;

实现 本地进程间 通信:「本地字节流 socket 」类型是 AF_LOCAL 和 SOCK_STREAM,「本地数据报 socket 」类型是AF_LOCAL 和 SOCK_DGRAM。ps:AF_UNIX 和 AF_LOCAL 是等价的,所以 AF_UNIX 也属于本地 socket;

3、三种通信编程模式

(1)TCP 协议通信socket 编程模型

1)服务端和客户端初始化 socket,得到文件描述符;

2)服务端调 bind ,绑定IP 地址和端口; 调 listen 监听; 调accept ,等待客户端连接;

3)客户端调 connect ,向服务器端的地址和端口发起连接请求;

4)服务端 accept 返回用于传输的 socket 文件描述符;ps:连接成功 返回已完成连接socket ,通过read 和 write

读写,像往文件流里面写东西一样

5)客户端调 write 写入数据;服务端调用 read 读取数据;

6)客户端 断开连接时调用 close ,那么服务端 read 读取数据时, 读到EOF,处理完close监听socket 和 真正 传数据socket (已完成连接 socket),是「 两个 」 socket

(2)针对 UDP 协议通信的 socket 编程模型

1) 只要 IP 地址端口号、bind ,UDP没连接,不需要三次握手,不需像 TCP 调listen 和 connect,。

2) 每次通信, 调sendto 和 recvfrom ,传入目标主机的 IP 地址端口

(3)本地进程间通信socket 编程模型

用于 同一主机通信 的,

1)接口和 IPv4 、IPv6 套接字编程一致,支持 「字节流」和「数据报」 两种协议;效率大大高于 IPv4 和 IPv6 字节流、数据报socket 实现;本地 字节流 socket ,socket 类型AF_LOCAL 和 SOCK_STREAM。本地 数据报 socket ,AF_LOCAL 和 SOCK_DGRAM。

2) 两个bind 时绑定一个本地文件, 不像 TCP 和 UDP 要绑定 IP 地址和端口,最大区别

总结

每个进程都共享一个内核空间,来通信

1、Linux 内核提供「匿名管道」和「命名管道」:都写入 缓存在内核 中,另一个进程也从内核读, 先进先出 ,不支持 lseek 文件定位

匿名: 「|」竖线就是匿名管道,通信数据 无格式的流并且大小受限单向 ,双向要建两个管道, 只能用于父子关系通信,随着进程创建而建,终止而消失

命名管道: 突破父子限制,使用前提,要文件系统创建类型 p 的设备文件。

2、消息队列:

解决管道无格式的字节流的问题,实际是保存在内核「消息链表」,用户可自定义消息体,发时被分成,一个个独立消息体,接时保持一致,不是最及时的,读写要经过用户态与内核态之间的拷贝过程。

3、共享内存:解决 拷贝开销, 直接分配共享空间,进程可直接访问 ,提高速度,缺点:多进程竞争同个共享资源错乱

4、信号量:实现 互斥访问。实际是计数器(资源个数), P 和 V 操作控制

5、信号唯一异步通信机制 ,在 应用 进程和 内核直接交互,内核用信号来通知用户,进程发生了哪些系统事件, 三种方式响应信号 1. 执行默认操作、2. 捕捉信号、3. 忽略信号 。ps:SIGKILL 和SEGSTOP无法捕捉和忽略,方便任何时候结束进程

6、Socket: 与不同主机的进程间通信,那么就需要 通信了 。根据Socket不同类型,分为三种通信方式, TCP、UDP、本地进程间

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
作者已关闭评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、匿名管道
  • 2、命名管道 FIFO
  • 3、创建原理
  • 二、消息队列
  • 三、共享内存
  • 四、信号量
    • 1、控制信号量两种原子操作:
      • 2、例:两进程互斥访问共享内存,初始化信号量1
      • 五、信号
        • 2、 给进程发送信号终端 输入组合键: Ctrl+C 产生 SIGINT 信号,终止进程;Ctrl+Z 产生 SIGTSTP 信号, 停止进程,未结束 ;
          • 3、进程对信号处理方式
          • 六、Socket
            • 1、创建 socket 系统调用int socket(int domain,int type, int protocal)
              • 2、不同socket 类型,通信方式不同
                • 3、三种通信编程模式
                • 总结
                相关产品与服务
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档