设计师学习网站,郑州东区网站优化公司推荐,学校网站建设报价,网站排名按天付费目录 什么是进程间通信
管道
匿名管道 什么是进程间通信
进程间通信#xff0c;顾名思义就是两个进程互相通信。
可是进程是独立的#xff0c;该如何通信呢#xff1f;
类比你和你的朋友在网上聊天#xff0c;你们两个人也是独立的#xff0c;是如何通信的呢#xf…
目录 什么是进程间通信
管道
匿名管道 什么是进程间通信
进程间通信顾名思义就是两个进程互相通信。
可是进程是独立的该如何通信呢
类比你和你的朋友在网上聊天你们两个人也是独立的是如何通信的呢因为你能看到你朋友给你发的消息你朋友也能看到这份消息。这个消息就是一个公共的资源。
所以进程间如果要进行通信就需要两个进程看到同一份资源。
那么通信的地点在哪里呢
很明显因为进程之间是独立的所以通信的地点肯定不能在进程中只能在操作系统中。 结论进程间通信的地点是操作系统。 进程间通信的方式有很多一般有三种
1.管道通过文件系统通信。
匿名管道命名管道
2. system V聚焦在本地通信
共享内存消息队列信号量
3. POSIX让通信可以跨主机。
共享内存消息队列信号量互斥量条件变量读写锁
本文主要讲管道的通信方式。
管道
回顾文件系统
当父进程打开一个文件时创建了一个子进程。子进程会继承父进程包括继承父进程的文件描述符。子进程和父进程相同的fd指向同一个文件。
到这里通信的条件就具有了因为父子进程看到了同一份文件。
说明:在冯诺依曼体系结构中磁盘是外设。而外设的读取速度是比较慢的。但是在进程间通信时他们并不关心磁盘中有什么文件 - - - 说白了就是不会和磁盘进行交互。于是为了提升效率就直接关闭了和磁盘中文件的交互。所以这种不进行IO通信的文件叫做内存级文件。
那么如果是内存级文件需要如何进行通信呢 1.父进程将内容写入到内存struct file的内存缓冲区中 2.子进程从内存struct file的内存缓冲区中读取数据。 总共发生两次拷贝 结论通过文件系统提供公共资源的进程间通信叫做管道。 匿名管道
理论
定义匿名管道就是没有名字的管道。
使用范围只能子在父子之间或者父亲的所有孩子兄弟之间进行通信也就是具有血缘关系才能通信。
原理
第一步父进程打开管道 从图中可以看到fd[0]对应的是读端对应父进程的3号文件描述符
fd[1]对应的是写端对应父进程的4号文件描述符。
fd[0]就是读端 fd[1]就是写端
第二步父进程创建子进程子进程会继承父进程的文件描述符 到这里父子进程通信的管道途径就建立好了但是管道就像水管一样只能单向通信。所以我们如果想要父进程写入子进程读取就需要关闭父进程的读端子进程的写端。
第三步父进程关闭读端写端子进程关闭写端读端 实践
查看手册查找pipe函数。 解读pipe函数的形参是一个pipefd[2]的数组该数组有两个元素分别是fd[0]和fd[1]其中pipefd[0]代表读端pipefd[1]代表写端。
返回值如果创建成功返回0否则返回-1。 实现通过管道使父子进程通信
打印结果 匿名管道读写特征四种
1.读快写慢
写入慢读取快read调用阻塞即进程暂停执行一直等到有数据来到为止
2.读慢写快
写入快读取慢write调用阻塞直到有进程读走数据。
3.写入端关闭读取端未关闭
管道写端对应的文件描述符被关闭则read返回0
当写入端关闭了读取端就没有等待的必要了读取端的read()直接返回0,表示写入端关闭了。
4.读取端关闭写入端未关闭
管道读端对应的文件描述符被关闭则write操作会产生信号SIGPIPE让write进程退出。 匿名管道实现简易进程池
processPool.cc文件 task.hpp文件 运行结果 命名管道
理论
使用范围命名管道可以实现任何进程之间的通信。 命名管道实现的过程
第一步创建命名管道 使用指令mkfifo 文件名 创建命名管道 创建命名管道之后该如何让不同的进程看到同一份资源呢
首先我们需要将这个命名管道做唯一标识。
其次让不同的文件都通过这个唯一标识就能确定双方找到的文件是同一份文件了。
就好像钥匙和锁一样。现在有很多钥匙A进程手里10把要是B进程手里10把钥匙现在A和B进程都找自己的钥匙只要能打开同一把锁就是相同的钥匙。
如何做到唯一标识
之前在文件系统中说到为什么同一个目录下的文件不能重名就是因为目录下存的是文件的文件名目录通过文件名找文件所以不能重名。
这里同理利用同一路径 文件名的方式唯一标识文件。 第二步进程之间使用命名管道通信
通信过程和匿名管道一样。 第三步删除命名管道如果不在程序中删除就要自己手动删除 使用指令unlink 文件名 实践
创建命名管道 参数 第一个参数是pathname,表示要创建的管道文件所在的路径和文件名 第二个参数是权限一般设置0666或者0664 作用 创建一个命名管道 返回值 如果创建成功则返回0否则返回-1 使用 进程之间使用命名管道通信
实现命名管道通信需要两个进程我们姑且将两个进程命名为客户端client和服务端sliver客户端发信息服务端接受信息。 客户端写入
服务端读取 服务端程序 只读端打开管道文件的方式是O_RDONLY。
接下来就是文件描述符fd中读取sizeof(buffer)个字节内容到buffer中。为了方便观察将buffer中的内容打印到显示器上。 客户端程序 写入端打开文件的时候使用O_WRONLY
之后将内容输入到line中将line中的内容写入到fd中拱读取端去读 实现进程间通信完整程序 实现日志