做sgs认证的公司网站,番禺高端网站制作,看今天的新闻,购物网站建设网站目录
#x1f308; 前言#x1f308;
#x1f4c1; 通信概念
#x1f4c1; 通信发展阶段
#x1f4c1; 通信方式
#x1f4c1; 管道#xff08;匿名管道#xff09;
#x1f4c2; 接口
编辑#x1f4c2; 使用fork来共享通道
#x1f4c2; 管道读写规则 前言 通信概念 通信发展阶段 通信方式 管道匿名管道 接口
编辑 使用fork来共享通道 管道读写规则 管道特征 命名管道 接口 管道和命名管道的区别 System V IPC 共享内存 原理 接口 消息队列 信号量 进程互斥 总结 前言 欢迎收看本期【Linux杂货铺】本期内容将讲解进程是如何实现通信的即资源共享。本篇文章主要聚焦于本地通信。重点讲解管道共享内存实现进程通信拓展了解消息队列信号量等内容。 通信概念 进程通信是什么这里就不做阐述了就如字面意思让进程之间信息交流。 通信的目的有 1. 数据传输一个进程需要将它的数据发送给另一个进程。 2. 资源共享多个进程之间共享同样的资源。 3. 通知事件一个进程需要向另一个或一组进程发送消息通知它们发生了某种事件如子进程终止通知父进程 4. 进程控制有些进程希望完全控制另一个进程的执行Debug进程此时控制进程希望能拦截另一个进程的所有陷入和异常并能及时知道它的状态。 通信发展阶段
在Linux中进程通信的发展阶段经历了几个阶段主要包含以下几个阶段 1. 初始阶段最早期的Linux内核中进程通信方式相对有限主要依赖于管道(Pipe) 和 信号(Signal)这样的基础机制。此时通信较为简单和有限。 2. System V IPC 随着Linux的发展引入了System V IPC它是一组用于进程间通信的APIApplication Programming Interface.System V IPC包括了共享内存Shared Memory、信号量Semaphore和消息队列Message Queue等机制。 3. POSIX IPC随着Linux逐渐趋近POSIXPortable Operating System Interface标准进程通信也逐渐向POSIX IPC过渡。POSIX IPC是一套与平台无关的进程通信接口包括命名管道Named Pipe、共享内存Shared Memory、信号量Semaphore和消息队列Message Queue等。 4. Socket编程随着互联网的兴起和网络技术的发展Socket编程成为Linux中重要的进程通信方式。通过Socket编程进程可以在不同主机之间进行通信实现远程进程间的通信和数据交换。 5. 其他高级通信机制随着分布式系统和多线程编程的发展还出现了更多高级的进程通信机制如RPCRemote Procedure Call远程过程调用、MPIMessage Passing Interface消息传递接口等。 通信方式
在Linux中我们可以将进程通信分为一下多种方式
1. 管道Pipe: 是一种半双工一段度另一端只能写的通信方式适用于具有父子关系的进程通信。可以实现一个进程将输出数据传递到另一个进程进行输入。
2. 命名管道Name Pipe是一种特殊的文件可用于不想管的进程之间通信。与普通管道不同命名管道通过文件系统进行访问。
3. 信号Signal是一种轻量级的进程通信机制用于在进程之间发送异步通知。一个进程向另一个进程发送信号接受方式根据不同信号类型采取相应的处理操作。
4. 共享内存Shared Memory共享内存是一种高效的进程间通信方式允许多个进程共享同一块物理内存区域。进程可以直接读写共享内存避免了数据的复制和传输开销。
5. 信号量Semaphore信号量是一种计数器用于控制多个进程对共享资源的访问。通过对信号量进行加减操作进程可以申请和释放共享资源实现进程间的互斥和同步。
6. 消息队列Message Queue消息队列是一种按照消息的方式进行进程间通信的机制。进程可以往消息队列中发送消息并从消息队列中接收消息实现异步通信和解耦合。
7. 套接字Socket套接字是一种网络编程接口也可以用于进程间通信。通过创建套接字进程可以在不同主机之间进行通信实现远程进程的通信和数据交换。 以上这些进程通信方式在Linux中都有对应的系统调用和库函数来支持开发者可以根据具体需求选择合适的方式进行进程间通信。 管道匿名管道 管道式Unix中最古老的进程间通信的形式。我们吧从一个进程链接到另一个进程的一个数据流称为一个“管道” 接口 #include unistd.h
功能:创建一无名管道
原型
int pipe(int fd[2]);
参数
fd文件描述符数组,其中fd[0]表示读端, fd[1]表示写端
返回值:成功返回0失败返回错误代码 使用fork来共享通道 通过文件描述符表来理解父子进程如何确定同一个通道。 在内核里管道的本质就是一块内核级的文件空间。 管道读写规则 1. 如果管道内部是空的 并且wfd没有关闭读取条件不具备所以读进程被阻塞等待读取条件成立即对端写入数据。 2. 向管道写并且rfd不读且没有关闭管道写满了写进程会被阻塞等待写条件具备即对端读取数据。 3. 管道一直在读但wfd写端关闭读端的read会读到0表示读到文件结尾。 4. 读端rfd关闭写端wfd不会一直写入一旦写入进程会杀掉。会给进程发送信号 13号信号。 管道特征 .1. 匿名管道只能用来进行具有血缘关系的进程之间进行通信常用于父子进程之间通信。 2. 管道内部自带进程之间同步的机制。 3. 管道文件的生命周期是随进程的。 4. 管道文件在通信的时候是面向字节流的write的次数和读取的次数不是一一匹配的。 5.管道的通信方式是一种特殊的半双工模式。 管道的特征对命名管道同样适应。 命名管道 管道应用的一个限制就是只能具有共同的祖先具有血缘关系的进程间通信。 如果我们想要不想管的进程之间通信可以使用命名管道FIFO。命名管道是一种特殊的文件。 管道匿名命名是内核级的不与磁盘进行交互即不会讲数据刷新到磁盘。 接口 命名管道之所以叫命名管道是因为需要有名字不同进程之间如何知道一个命名管道呢就是通过具有唯一性的文件路径通过文件路径找到这个命名管道并进行文件读写操作。 因此我们在创建命名管道的时候需要提供文件路径以此来创建命名管道文件。
指令
mkfifo filename系统调用
int mkfifo(const char *filename,mode_t mode);mode是指权限。
//创建管道文件#include iostream
#include sys/types.h
#include sys/stat.hint main()
{mkfifo(./fifo,0x666);return 0;
} 删除管道指令
unlink filename删除管道接口
#include unistd.hint unlink(const char* pathname)
#include iostream
#include sys/types.h
#include sys/stat.h
#include unistd.hint main()
{mkfifo(./fifo,0x666);sleep(5); //过5秒后清除命名管道文件unlink(./fifo);return 0;
} 管道和命名管道的区别 1. 管道通过pipe函数创建并打开。 2. 命名管道有mkfifo函数创建打开用open。 3. FIFO命名管道和 pipe匿名管道之间唯一的区别分别在它们的创建与打开的方式不同一旦这些工作完成之后它们具有相同的意义。 System V IPC System V IPCInter-Process Communication是一种在Unix-like操作系统中用于进程间通信的机制。它提供了三种主要的IPC对象消息队列Message Queues、信号量Semaphores和共享内存Shared Memory这些对象允许不同的进程在同一台计算机上进行通信和共享数据。 经过不断发展进程通信有了更好的方式即通过网络进行通信所以单纯的本地通信已经很少用到因此我们将主要讲解共享内存因为相比较足够简单如果感兴趣可以学习了解消息队列和信号量。 共享内存 共享内存区是最快的IPC形式。一旦这样的内存映射到共享它的进程的地址空间这些进程间数据传递不再涉及到内核换句话说是进程不再通过执行进入内核的系统调用来传递彼此的数据。 原理 在物理内存中创建一段空间建立与虚拟地址空间的映射映射到虚拟地址空间中的共享区。此后两进程的通信再也不需要再进入内核态调用系统调用直接通过代码读写共享区即可例如malloc出一段空间通过指针来使用这段空间。 对于上面操作需要理解 1. 以上操作都是OS操作的如共享内存的映射。 2. OS必须提供系统调用供进程使用。如开辟共享内存。 3. 共享内存可以在系统中存在多份供不同个数不同进程进行通信。 4. OS要对共享内存进行管理即共享内存不是简单的一段内存空间也要有描述和管理共享内存的数据结构和匹配算法。 5. 共享内存 内存空间数据 属性。 接口 1. 创建一个共享内存
#include sys/ipc.h
#include sys/shm.h
int shmget(key_t key, size_t size, int shmflg);a. size是用来指示共享内存空间的大小。
b. shmflag用于指定共享内存区域的权限和选项。IPC_CREAT 和 IPC_EXCL IPC_CREAT如果要创建的共享内存在OS内不存在就创建如果存在就获取并返回。 IPC_EXCL不能单独使用必须和IPC_CREAT组合。 IPC_CREAT | IPC_EXCL如果不存在创建存在出错并返回。
c. key唯一标识共享内存区域的键值。这是用户提供给系统使用的具有唯一性的键值。 这里为什么要用户自己提供呢不可以OS自己生成一个吗不可以我们的出发点就是通过共享内存实现两个进程通信如果两个进行都知道这个key那还大费周章干什么直接通信就好了。
d. 返回值 shmid也是一个唯一标识共享区域的键值。不过它是系统提供给用户使用的。这主要是为了解耦。
shmid 与 key 的区别
1. key是用户设置内核使用的字段用户不能使用key来进行shm管理。key是内核区分shm唯一性的。
2. shmid是内核返回给用户的一个标识符用来进行用户级对共享内存进行操作的。 2. 挂载共享内存 共享内存想要使用必须先将物理内存与虚拟内存进行映射。因此需要将共享内存挂接。
#include sys/types.h
#include sys/shm.h//挂接 , 只需要输入shmid 即可 其他分别输入 nullptr , 0
//失败返回0成功返回共享内存的起始地址。
void *shmat(int shmid, const void *shmaddr, int shmflg);//取消挂接,只需要输入挂接成功后返回的地址。
int shmdt(const void *shmaddr);3. 删除共享内存
#include sys/ipc.h
#include sys/shm.hint shmctl(int shmid, int cmd, struct shmid_ds *buf);
//第二个参数为 IPC_RMID , 第三个参数为 nullptr4. 指令查看 和 删除
ipcs -m : 查看ipcrm -m shmid : 删除 此外我们还需要认识到共享内存/消息队列/信号量 的生命周期随内核的即进程的结束并不会受到影响必须手动释放指令 或 系统调用否则会一直存在。 管道的生命周期随内核。 消息队列 消息队列提供了一个从一个进程向另外一个进程发送一块数据的方法 每个数据块都被认为是有一个类型接收者进程接收的数据块可以有不同的类型值 特性方面 IPC资源必须删除否则不会自动清除除非重启所以system V IPC资源的生命周期随内核 信号量 严格来说信号量是一种用于实现进程间同步和互斥的机制通过它可以控制对共享资源的访问。 信号量是一种计数器用于控制多个进程对共享资源的访问。通过对信号量进行加减操作进程可以申请和释放共享资源实现进程间的互斥和同步。 需要经过申请信号量访问共享内存释放信号量 这几个过程。 因为信号量本身是一种共享资源需要被所有进程看到因此也列为进程通信的范畴。 进程互斥
我们需要重申几个概念
1. 多个执行流能看到的一份资源共享资源。
2. 被保护起来的资源叫做 临界资源。保护资源的方式同步 and 互斥。
3. 互斥 任何时刻只能有一个进程在访问共享资源。
4. 代码 访问共享资源的代码临界区 不访问公共享资源的代码非临界区
5. 对共享资源进行保护本质是对共享资源的代码进行保护。 由于各进程要求共享资源而且有些资源需要互斥使用因此各进程间竞争使用这些资源进程的这种 关系为进程的互斥。 系统中某些资源一次只允许一个进程使用称这样的资源为临界资源或互斥资源。 在进程中涉及到互斥资源的程序段叫临界区。 在多线程的章节里我们会讲解信号量这里先做一定的了解。 总结 因此进程本地通信的方式截止目前我们学习了管道命名管道共享内存了解了消息队列和信号量。介绍了进程通信的发展历史阶段上述三种通信方式的系统调用接口和指令。拓展了进程互斥的概念为日后学习多线程做了铺垫。 以上就是本期【Linux杂货铺】的主要内容了如果感觉本篇文章对你有帮助欢迎点赞收藏关注Thanks♪(ω)