进程通讯:管道

管道,通常指无名管道,是 UNIX 系统IPC最古老的形式。

1、特点:

  • 它是半双工的(即数据只能在一个方向上流动),具有固定的读端和写端。
  • 它只能用于具有亲缘关系的进程之间的通信(也是父子进程或者兄弟进程之间)。
  • 它可以看成是一种特殊的文件,对于它的读写也可以使用普通的read、write 等函数。但是它不是普通的文件,并不属于其他任何文件系统,并且只存在于内存中。

1). 当一个管道建立时,它会创建两个文件描述符:fd[0]为读而打开,fd[1]为写而打开。如下图: 

要关闭管道只需将这两个文件描述符关闭即可。

2). 单个进程中的管道几乎没有任何用处。所以,通常调用 pipe 的进程接着调用 fork,这样就创建了父进程与子进程之间的 IPC 通道。如下图所示:

 

1. 测试代码:

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>int main(int argc, char *argv[])
{int pipefd[2];int ret, nwrite, nread;pid_t pid;char writebuf[1024];char readbuf[1024];ret = pipe(pipefd);if (ret == -1){perror("pipe");return -1;}pid = fork();if (pid == -1){perror("fork");return -1;}else if (pid == 0){close(pipefd[1]);while (1){nread = read(pipefd[0], readbuf, sizeof(readbuf));if (nread == -1){perror("read");exit(-1);}printf("read from pipe %s\n", readbuf);if (!strncmp(readbuf, "quit", 4))break;}}if (pid > 0){close(pipefd[0]);while (1){fgets(writebuf, sizeof(writebuf), stdin);nwrite = write(pipefd[1], writebuf, sizeof(writebuf));if (nwrite == -1){perror("write");exit(-1);}if (!strncmp(writebuf, "quit", 4))break;}}
}

输出结果:

 

有名管道

1. 为何提出有名管道的说法,目的是为了克服无名管道的不足之处:

  • 无名管道只能是用于具有亲缘关系的进程之间,这就限制了无名管道的使用范围。
  • 有名管道可以使互不相关的两个进程互相通信,有名管道可以通过路径名来指出。并在文件系统课件为了这种有名管道,Linux中专门设立了一个专门的特殊文件系统-管道文件,以FIFO的形式存在于文件系统中,这样,即使与FIFO的创建者不存在亲缘关系的进程,只要访问该路径,就能彼此通过FIFO相互通信,因此,通过FIFO不相关的进程也能交换数据,但在磁盘只是一个节点,而文件的数据只存在内存缓冲页面上,与普通管道一样。

2. 有名管道的创建

有名管道可以从命令行上创建,命令行方法是使用下面这个命令:

$ mkfifo myfifo

有名管道也可以从程序里创建,相关API有:

int mkfifo(cosnt char *path, mode_t mode);

参数:

  • 第一个参数是一个普通的路径名,也就是创建后FIFO名字。
  • 第二个参数与打开普通文件的open函数中的mode参数相同(文件的读写权限),如果mkfifo的一个参数是一个已经存在路径名时,会返回EEXIST错误,所以一般典型的调用代码会检查是否返回该错误,如果确实返回该错误,那么要调用打开FIFO的函数open就可以了。

3. FIFO的open函数打开规则:
O_RDONLY、O_WRONLY和O_NONBLOCK标志共有四种合法的组成方式:

flags = O_RDONLY:open将会调用阻塞,除非有另外一个进程以写的方式打开用一个FIFO,否则一直等待。
flags = O_WRONLY:open将会调用阻塞,除非有另外一个进程以读的方式打开同一个FIFO,否则一直等待。
flags = O_RDONLY | O_NONBLOCK:如果此时没有其他进程以写的方式打开FIFO,此时open也会成功返回,此时FIOF被读打开,而不会返回错误。
flag是= O_WRONLY | O_NONBLOCK:立即返回,如果此时没有其他进程以读的方式打开,open会失败打开,此时FIOF没有被打开,返回-1。
 

 

 程序1:
 

// writefifo.c
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>int main(int argc, const char *argv[])
{int fd, nwrite;char buf[1024] = "\0";if (access(argv[1], F_OK) != 0){int ret = mkfifo(argv[1], 0666);if (ret == -1){perror("mkfifo");exit(-1);}}fd = open(argv[1], O_WRONLY);if (fd == -1){perror("open");return -1;}while (1){fgets(buf, sizeof(buf), stdin);buf[strlen(buf) - 1] = '\0';nwrite = write(fd, buf, strlen(buf));if (nwrite == -1){perror("write error");return -1;}if (!strncmp(buf, "quit", 4))break;}return 0;
}

程序2:

//readfifo.c
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
int main(int argc, const char *argv[])
{int ret, fd, nread;char buf[1024] = "\0";if (access(argv[1], F_OK) != 0){ret = mkfifo(argv[1], 0666);if (ret == -1){perror("mkfifo");exit(-1);}}fd = open(argv[1], O_RDONLY);if (fd == -1){perror("open");exit(-1);}while (1){nread = read(fd, buf, sizeof(buf));if (nread == -1){perror("read errro");exit(-1);}printf("read from fifo is %s\n", buf);if (!strncmp(buf, "quit", 4))break;memset(buf, '\0', sizeof(buf));}return 0;
}

输出结果: 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/385656.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java基础入门答案谭晓芳,原理+实战讲解

One&#xff1a;JVM实践思维图&#xff08;完整版&#xff09; Two&#xff1a; 走近Java 概述 Java技术体系Java发展史Java虚拟机家族&#xff1a;&#xff08;Sun Classic/Exact VM、HotSpot VM、Mobile/Embedded VM、BEA JRockit/IBM J9 VM、BEA Liquid VM/Azul VM、Apache…

Leetcode 102. 二叉树的层次遍历

给定一个二叉树&#xff0c;返回其按层次遍历的节点值。 &#xff08;即逐层地&#xff0c;从左到右访问所有节点&#xff09;。 例如: 给定二叉树: [3,9,20,null,null,15,7], 3 / \ 9 20 / \ 15 7 返回其层次遍历结果&#xff1a; [ [3], [9,20], [15,7…

java基础常问面试题,面试必问

一、首先本职工作一定要做好做精 本人之前在干兼职的时候&#xff0c;也忽视过本职工作&#xff0c;从而导致自己落后平均技术水平&#xff0c;虽然之后迎头赶上&#xff0c;但这不能不算是个遗憾。前在接一些活的时候就感觉技术的重要性了&#xff0c;如果当年我技术再好些&a…

Leetcode | 107. Binary Tree Level Order Traversal II

题目&#xff1a;二叉树的层次遍历 II 1. 代码①&#xff1a;深度优先搜索(链接&#xff09; /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode(int x) : val(x), left(NULL), right(NUL…

java基础教程哪个好,吐血整理

RabbitMQ&#xff1a; 优点&#xff1a;轻量&#xff0c;迅捷&#xff0c;容易部署和使用&#xff0c;拥有灵活的路由配置 缺点&#xff1a;性能和吞吐量较差&#xff0c;不易进行二次开发 RocketMQ&#xff1a; 优点&#xff1a;性能好&#xff0c;稳定可靠&#xff0c;有活…

java基础教程哪个好,面试必会

如何才可以进大厂&#xff1f; 答案其实也很简单&#xff0c;能力学历。不知道大家有没有发现&#xff0c;大厂的一些部门对于学历要求已经放低了&#xff0c;阿里的一些部门同样也招大专学历的程序员&#xff0c;当然肯定也是因为他的能力足够出色。 对于准备秋招的你来说&a…

java基础教程第三版耿祥义,后台开发JAVA岗

Java虚拟机内存模型 Java虚拟机内存模型中定义的访问操作与物理计算机处理的基本一致&#xff01; Java中通过多线程机制使得多个任务同时执行处理&#xff0c;所有的线程共享JVM内存区域main memory&#xff0c;而每个线程又单独的有自己的工作内存&#xff0c;当线程与内存区…

501. 二叉搜索树中的众数

给定一个有相同值的二叉搜索树&#xff08;BST&#xff09;&#xff0c;找出 BST 中的所有众数&#xff08;出现频率最高的元素&#xff09;。 假定 BST 有如下定义&#xff1a; 结点左子树中所含结点的值小于等于当前结点的值结点右子树中所含结点的值大于等于当前结点的值左…

java基础案例教程黑马程序员案例答案,真香

掌握核心知识 1、90%几率面试被问&#xff0c;吃透原理&#xff0c;面试不慌&#xff08;Spring原理&#xff09; 2、大厂必问Redis&#xff0c;赶紧码起来&#xff08;Redis核心原理&#xff09; 3、MySQL从入门到实战都在这篇&#xff0c;面试笑谈优化 当然核心知识不止这三…

java基础的三个框架,进阶学习资料!

阿里巴巴一面 自我介绍这个就不说了&#xff0c;开头必问的说一下StringBuilder 和 StringBufferSpring bean加载&#xff0c;实例化的过程Spring AOP源码看过吗java内存模型说一下如果给你一个map&#xff0c;里面有很多很多对象&#xff0c;那么这个map存放在哪了解GC算法吗…

实验3 | 由遍历序列构造二叉树

二叉树构造定理&#xff1a; 定理7.1&#xff1a;任何n&#xff08;n>0&#xff09;个不同结点的二又树&#xff0c;都可由它的中序序列和先序序列唯一地确定。 定理7.2&#xff1a;任何n&#xff08;n&#xff1e;0&#xff09;个不同结点的二又树&#xff0c;都可由它的…

万字总结!java让字符串反转

Java基础 JDK 和 JRE 有什么区别&#xff1f; 和 equals 的区别是什么&#xff1f;两个对象的 hashCode()相同&#xff0c;则 equals()也一定为 true&#xff0c;对吗&#xff1f;final 在 java 中有什么作用&#xff1f;java 中的 Math.round(-1.5) 等于多少&#xff1f;Stri…

String | 344. Reverse String

题目&#xff1a;反转字符串 方法1&#xff1a; class Solution { public:string reverseString(string s) {int m (s.size() -1) / 2;for(int i 0; i < m; i){char c s[i];s[i] s[s.size() -1 - i];s[s.size() -1 - i] c;}return s; } }; 方法2&#xff1a;…

万字总结!springcloud分布式限流

正文 作为后端开发&#xff0c;日常操作数据库最常用的是写操作和读操作。读操作我们下边会讲&#xff0c;这个分类里我们主要来看看写操作时为什么会导致 SQL 变慢。 刷脏页 脏页的定义是这样的&#xff1a;内存数据页和磁盘数据页不一致时&#xff0c;那么称这个内存数据页…

String | 263. Ugly Number

题目&#xff1a;丑数 方法1 class Solution { public:bool isUgly ( int num ) {if (num 0)return false;while (num % 5 0)num / 5;while (num % 3 0)num / 3;while (num % 2 0)num / 2;return num 1;} };

万字长文!java读取json文件数据给对象

Java基础核心笔记总结 由于篇幅限制&#xff0c;我就只以截图展示目录内容以及部分笔记内容&#xff0c;获取完整版王者级核心宝典只需要点击点赞关注即可获取领取方式&#xff01; 在这个部分我们总结了Java的基础知识&#xff0c;涵盖了&#xff1a;概述、开发环境、开发环境…

三年Java开发,java基础常问面试题

一、首先本职工作一定要做好做精 本人之前在干兼职的时候&#xff0c;也忽视过本职工作&#xff0c;从而导致自己落后平均技术水平&#xff0c;虽然之后迎头赶上&#xff0c;但这不能不算是个遗憾。前在接一些活的时候就感觉技术的重要性了&#xff0c;如果当年我技术再好些&a…

Array | 867. Transpose Matrix

题目&#xff1a;转置矩阵 方法1&#xff1a; class Solution { public:vector<vector<int>> transpose(vector<vector<int>>& A) {vector<vector<int>> num(A[0].size(), vector<int>(A.size(), 0));for(int i 0; i < A.…

三年Java开发,尚学堂java马士兵全套

基于 Servlet 容器的 Web MVC 身为 Java 开发者&#xff0c;对于 Spring 框架并不陌生。它起源于 2002 年、Rod Johnson 著作《Expert One-on-One J2EE Design and Development》中的 Interface 21 框架&#xff0c;到了 2004 年&#xff0c;推出 Spring 1.0&#xff0c;从 XM…

Array | 74. Search a 2D Matrix

题目&#xff1a;搜索二维矩阵 方法1&#xff1a; class Solution { public:bool searchMatrix(vector<vector<int>>& matrix, int target) {if(!matrix.size())return false;if(!matrix[0].size())return false;for(int i 0; i < matrix[matrix.size() …