进程通讯:管道

管道,通常指无名管道,是 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…

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

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

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;当线程与内存区…

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…

万字总结!springcloud分布式限流

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

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

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

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

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

三年经验java工资,含爱奇艺,小米,腾讯,阿里

1、PTP模型 Point-to-Point&#xff0c;点对点通信模型。PTP是基于队列(Queue)的&#xff0c;一个队列可以有多个生产者&#xff0c;和多个消费者。消息服务器按照收到消息的先后顺序&#xff0c;将消息放到队列中。队列中的每一条消息&#xff0c;只能由一个消费者进行消费&a…

三面美团Java岗,java多线程匿名内部类

Part 1微服务架构设计概述 1.1 传统应用架构的问题 1.2 微服务架构是什么 1.3 微服务架构有哪些特点和挑战 1.4 如何搭建微服务架构 Part 2微服务开发框架 2.1 Spring Boot 是什么 2.2 如何使用Spring Boot框架 2.3 Spring Boot生产级特性 Part 3微服务网关 3.1 Node.js 是什…

函数signal

1. 函数signal #include <signal.h> void (*signal(int sig,void (*func)(int)))(int)typedef void (*sighandler_t)(int); sighandler_t signal(int signum, sighandler_t handler); 分析&#xff1a; signal参数信号名&#xff0c;func的值是SIG_ING、SIG_DFL或接到…

三面美团Java岗,java架构师线下培训

性能优化专栏 1.Tomcat性能优化整理 2.JVM性能优化专题 3.Mysql性能优化整理 微服务架构面试专栏 1.SpringCloud面试整理 2.SpringBoot面试整理 3.Dubbo面试整理 并发编程高级面试专栏 开源框架面试题专栏 1.Spring面试整理 2.SpringMVC面试整理 3.MyBatis面试整理 分布式面…

信号 09 | SIGCLD语义

1. SIGCLD信号 SIG_DFL &#xff1a;默认的处理方式是不理会这个信号&#xff0c;但是也不会丢弃子进程状态&#xff0c;所以如果不用wait&#xff0c;waitpid对其子进行进行状态信息回收&#xff0c;会产生僵尸进程。SIG_IGN &#xff1a;忽略的处理方式&#xff0c;这个方式…

三面美团Java岗,java电子书下载百度云

Spring 全家桶&#xff1a; Spring 原理Spring面试题思维导图面试题Spring视频 Spring 原理 Spring特点Spring 核心组件Spring常用模块Spring主要包Spring常用注解Sping第三方结合Spring 10C原理Spring APO原理Spring MVC原理Spring Boot原理JPA原理Mybatis缓存Tomcat架构 Sp…

【信号】函数kill、raise、abort、alarm

一、函数kill 1. kill函数原型&#xff1a; int kill(pid_t pid, int signo); //signo:信号名分析&#xff1a; pid > 0&#xff1a; 发送信号给指定的进程pid 0&#xff1a; 发送信号给调用kill函数进程属于同一个进程组的所有进程pid < 0&#xff1a;信号signo将…