linux多进/线程编程(4)——进程间通信之pipe和fifo
前言:
Linux环境下,进程地址空间相互独立,每个进程各自有不同的用户地址空间。任何一个进程的全局变量在另一个进程中都看不到,所以进程和进程之间不能相互访问,要交换数据必须通过内核,在内核中开辟一块缓冲区,进程1把数据从用户空间拷到内核缓冲区,进程2再从内核缓冲区把数据读走,内核提供的这种机制称为进程间通信(IPC,InterProcess Communication)。
常用的进程间通信方式有:
① 管道 (使用最简单)
② 信号 (开销最小)
③ 共享映射区 (无血缘关系)
④ 本地套接字 (最稳定) https://zhuanlan.zhihu.com/p/336734605
本文主要讲解pipe管道的用法和代码示例。
- 管道是一种最基本的IPC机制,作用于有血缘关系的进程之间,完成数据传递。调用pipe系统函数即可创建一个管道。有如下特质:
- 1. 其本质是一个伪文件(实为内核缓冲区)
- 2. 由两个文件描述符引用,一个表示读端,一个表示写端。
- 3. 规定数据从管道的写端流入管道,从读端流出。
- 管道的原理: 管道实为内核使用环形队列机制,借助内核缓冲区(4k)实现。
管道的局限性:
- 1. 数据一旦被读走,便不在管道中存在,不可反复读取。
- 2. 由于管道采用半双工通信方式。因此,数据只能在一个方向上流动。
- 3. 只能在有公共祖先的进程间使用管道。
pipe
- NAME
- pipe, pipe2 - create pipe
- SYNOPSIS
- #include <unistd.h>
- int pipe(int pipefd[2]);
- #define _GNU_SOURCE /* See feature_test_macros(7) */
- #include <fcntl.h> /* Obtain O_* constant definitions */
- #include <unistd.h>
- int pipe2(int pipefd[2], int flags);
利用pipe实现ps aux | grep bash
- int pipe_fd[2];
- pipe(pipe_fd);
- pid_t pid = fork();
- if (pid == 0) {
- //son -----> 这里会产生僵尸进程
- //管道的使用规范:关闭读端
- close(pipe_fd[0]);
- //1.先重定向
- dup2(pipe_fd[1], STDOUT_FILENO);//标准输出重定向到管道写端
- //2.execlp
- execlp("ps", "ps", "aux", nullptr);
- } else if (pid > 0) {
- //parent
- //管道的使用规范:关闭写端
- close(pipe_fd[1]);
- //1.先重定向
- dup2(pipe_fd[0], STDIN_FILENO);//标准输入重定向到管道读端
- //2.execlp -----> grep 会阻塞
- execlp("grep", "grep", "--color=auto", "bash", nullptr);
- //代码的问题:父进程认为还有写端存在,就有可能还有人给发数据,继续等待
- //管道的使用规范
- }
fifo 可以实现无血缘关系的进程间通信
- #include <stdio.h>
- #include <unistd.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <string.h>
- int main(int argc, char * argv[]) {
- if (argc != 2) {
- printf("./a.out fifonname\n");
- return -1;
- }
- //当前目录有一个myfifo文件
- //打开fifo文件
- int fd = open(argv[1], O_WRONLY);
- //写
- char buf[256];
- int num = 1;
- while(1) {
- memset(buf, 0x00, sizeof(buf));
- //循环写
- sprintf(buf, "xiaoming%04d", num++);
- write(fd, buf, strlen(buf));
- sleep(1);
- }
- //关闭描述符
- closde(fd);
- return 0;
- }
- #include <stdio.h>
- #include <unistd.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <string.h>
- int main(int argc, char * argv[]) {
- if (argc != 2) {
- printf("./a.out fifonname\n");
- return -1;
- }
- //当前目录有一个myfifo文件
- //打开fifo文件
- int fd = open(argv[1], O_RDONLY);
- char buf[256];
- int ret = 0;
- while(1) {
- //循环读
- ret = read(fd, buf, sizeof(buf));
- if (ret > 0) {
- printf("read:%s\n", buf);
- }
- }
- //关闭描述符
- closde(fd);
- return 0;
- }
linux多进/线程编程(4)——进程间通信之pipe和fifo的更多相关文章
- linux多进/线程编程(7)——多线程1(线程的创建,回收,分离,设置线程属性等)
参考资料: 1.博客1:https://blog.csdn.net/zhou1021jian/article/details/71531699 2.博客2:https://blog.csdn.net/ ...
- linux多进/线程编程(5)——进程间通信之mmap
参考资料: 1.博客1:https://www.jianshu.com/p/755338d11865 mmap:一种内存映射文件的方法 memory map 父子进程和无亲缘关系的进程,都可以将自身用 ...
- linux多进/线程编程(2)—— fork函数和进程间“共享”数据
参考: 1.博客1:https://www.pianshen.com/article/4305691855/ fork:在原进程的基础上"分叉"出一个子进程,即创建一个子进程. N ...
- linux多进/线程编程(3)——wait、waitpid函数和孤儿、僵尸进程
当使用fork创建多个进程后,需要解决子进程回收的问题.wait和waitpid函数就是做这个工作的. 假设子进程没有合理的回收,可能会带来两个问题: 1.孤儿进程(父进程挂了,子进程活着),孤儿进程 ...
- linux多进/线程编程(1)—— 基础概念(PCB、MMU、进程状态)
学习大概就是不断迭代.重构的过程,不复习的学习是不负责任的,亦是无用的. 本系列博客主要作为个人记录,主要是贴图和代码,不做详细解释,以后有时间可能会重写:从下一篇开始上代码,代码可以运行是对自己的最 ...
- 《Linux多线程服务端编程》笔记——线程同步精要
并发编程基本模型 message passing和shared memory. 线程同步的四项原则 尽量最低限度地共享对象,减少需要同步的场合.如果确实需要,优先考虑共享 immutable 对象. ...
- Linux线程编程之信号处理
前言 Linux多线程环境中的信号处理不同于进程的信号处理.一方面线程间信号处理函数的共享性使得信号处理更为复杂,另一方面普通异步信号又可转换为同步方式来简化处理. 本文首先介绍信号处理在进程中和线程 ...
- linux网络编程之进程间通信介绍
从今天起,开始学习进程间通信相关的东东,关于socket的编程先告一段落了,在学习进程间通信之前,首先先要了解一些概念,所以,这次不开始真正的代码编写,先纯理论,理解了为之后的更深入的学习可以打下良好 ...
- 一、智能指针及线程同步总结------linux多线程服务端编程
更新2.0 二.多线程及服务器编程总结------linux多线程服务端编程 https://www.cnblogs.com/l2017/p/11335609.html 三.分布式编程总结------ ...
随机推荐
- css中设置背景图片适应屏幕
以body为例 body{ background: url(../img/jld.png) no-repeat center center fixed; -webkit-background-size ...
- linux实时监控并实时备份数据(rsync)
目录 一:rsync实时监控备份流程 1.安装rsync(服务端 与 客服端)守护进程模式 2.修改配置文件(服务端) 3.解析配置内容 4.创建系统用户 5.创建密码文件 6.授权(必须授权为600 ...
- linux挂载windows nfs
1.win下创建nfs文件夹并共享 2.登陆linux,执行 yum 3.创建挂载点 4.挂载win nfs 5./etc/fstab添加永久挂载 6.查看挂载磁盘,此时windows盘已落在linu ...
- l线程池抓取lianjia
1. 线程池 的应用 from multiprocessing.dummy import Pool import requests from lxml import etree url="h ...
- django入门 02 初探app、view、url、templates、static
创建APP命令 python manage.py startapp myapp app组成介绍 如上图,在终端中展示树状结构-- windows为 tree /f macOS为 tree 注册APP ...
- Nginx网络压缩 CSS压缩 图片压缩 JSON压缩
一.序言 使用Nginx作为web应用服务时,会代理如下常见文件:js.css.JSON.图片等,本文提供基于Nginx内置的压缩技术,提供网络请求响应速度的解决方案. 1.网络压缩原理 网络压缩的原 ...
- 多种方式告诉你如何计算DM同步数据到TiDB的延时时间
背景 用户在做技术选型的过程中,总是会对一些数据指标比较关心,特别是在和竞品相比较的时候,更加需要一些有说服力的数据.基于MySQL开发的项目在迁移到TiDB的时候,使用DM同步数据是必不可少的一个环 ...
- Mysql一个主一备
Mysql主从复制 -- 一主一备 主从复制原理: Mysql的主从复制是mysql本身自带的一个功能,不需要额外的第三方软件可以实现,其复制功能并不是copy文件实现的,而是借助binlog日志文件 ...
- JS 解构赋值
感谢原文作者:小火柴的蓝色理想 原文链接:https://www.cnblogs.com/xiaohuochai/p/7243166.html 介绍 解构赋值语法是一种 Javascript ES6引 ...
- 乐动ld06激光雷达sdk改bug记录分享
前言: 工作中,有使用过乐动ld06款激光雷达,此款雷达将常规雷达的转动的电机部分内置于自己的保护罩内,减少了雷达本身转动积灰等其他外界影响,探测半径是12m,是一款不错的雷达. 不过今天的主要内容不 ...