前言:

Linux环境下,进程地址空间相互独立,每个进程各自有不同的用户地址空间。任何一个进程的全局变量在另一个进程中都看不到,所以进程和进程之间不能相互访问,要交换数据必须通过内核,在内核中开辟一块缓冲区,进程1把数据从用户空间拷到内核缓冲区,进程2再从内核缓冲区把数据读走,内核提供的这种机制称为进程间通信(IPC,InterProcess Communication)。

常用的进程间通信方式有:

① 管道 (使用最简单)

② 信号 (开销最小)

③ 共享映射区 (无血缘关系)

④ 本地套接字 (最稳定) https://zhuanlan.zhihu.com/p/336734605

本文主要讲解pipe管道的用法和代码示例。

  1. 管道是一种最基本的IPC机制,作用于有血缘关系的进程之间,完成数据传递。调用pipe系统函数即可创建一个管道。有如下特质:
  2.   1. 其本质是一个伪文件(实为内核缓冲区)
  3.   2. 由两个文件描述符引用,一个表示读端,一个表示写端。
  4.   3. 规定数据从管道的写端流入管道,从读端流出。
  5. 管道的原理: 管道实为内核使用环形队列机制,借助内核缓冲区(4k)实现。

管道的局限性:

  1. 1. 数据一旦被读走,便不在管道中存在,不可反复读取。
  2. 2. 由于管道采用半双工通信方式。因此,数据只能在一个方向上流动。
  3. 3. 只能在有公共祖先的进程间使用管道。

pipe

  1. NAME
  2. pipe, pipe2 - create pipe
  3.  
  4. SYNOPSIS
  5. #include <unistd.h>
  6.  
  7. int pipe(int pipefd[2]);
  8.  
  9. #define _GNU_SOURCE /* See feature_test_macros(7) */
  10. #include <fcntl.h> /* Obtain O_* constant definitions */
  11. #include <unistd.h>
  12.  
  13. int pipe2(int pipefd[2], int flags);

利用pipe实现ps aux | grep bash

  1. int pipe_fd[2];
  2. pipe(pipe_fd);
  3.  
  4. pid_t pid = fork();
  5.  
  6. if (pid == 0) {
  7. //son -----> 这里会产生僵尸进程
  8. //管道的使用规范:关闭读端
  9. close(pipe_fd[0]);
  10. //1.先重定向
  11. dup2(pipe_fd[1], STDOUT_FILENO);//标准输出重定向到管道写端
  12. //2.execlp
  13. execlp("ps", "ps", "aux", nullptr);
  14. } else if (pid > 0) {
  15. //parent
  16. //管道的使用规范:关闭写端
  17. close(pipe_fd[1]);
  18. //1.先重定向
  19. dup2(pipe_fd[0], STDIN_FILENO);//标准输入重定向到管道读端
  20. //2.execlp -----> grep 会阻塞
  21. execlp("grep", "grep", "--color=auto", "bash", nullptr);
  22. //代码的问题:父进程认为还有写端存在,就有可能还有人给发数据,继续等待
  23. //管道的使用规范
  24. }

fifo 可以实现无血缘关系的进程间通信

  1. #include <stdio.h>
  2. #include <unistd.h>
  3. #include <sys/types.h>
  4. #include <sys/stat.h>
  5. #include <fcntl.h>
  6. #include <string.h>
  7.  
  8. int main(int argc, char * argv[]) {
  9. if (argc != 2) {
  10. printf("./a.out fifonname\n");
  11. return -1;
  12. }
  13. //当前目录有一个myfifo文件
  14. //打开fifo文件
  15. int fd = open(argv[1], O_WRONLY);
  16. //写
  17. char buf[256];
  18. int num = 1;
  19. while(1) {
  20. memset(buf, 0x00, sizeof(buf));
  21. //循环写
  22. sprintf(buf, "xiaoming%04d", num++);
  23. write(fd, buf, strlen(buf));
  24. sleep(1);
  25. }
  26.  
  27. //关闭描述符
  28. closde(fd);
  29.  
  30. return 0;
  31. }
  1. #include <stdio.h>
  2. #include <unistd.h>
  3. #include <sys/types.h>
  4. #include <sys/stat.h>
  5. #include <fcntl.h>
  6. #include <string.h>
  7.  
  8. int main(int argc, char * argv[]) {
  9. if (argc != 2) {
  10. printf("./a.out fifonname\n");
  11. return -1;
  12. }
  13. //当前目录有一个myfifo文件
  14. //打开fifo文件
  15. int fd = open(argv[1], O_RDONLY);
  16.  
  17. char buf[256];
  18. int ret = 0;
  19. while(1) {
  20. //循环读
  21. ret = read(fd, buf, sizeof(buf));
  22. if (ret > 0) {
  23. printf("read:%s\n", buf);
  24. }
  25. }
  26.  
  27. //关闭描述符
  28. closde(fd);
  29.  
  30. return 0;
  31. }

linux多进/线程编程(4)——进程间通信之pipe和fifo的更多相关文章

  1. linux多进/线程编程(7)——多线程1(线程的创建,回收,分离,设置线程属性等)

    参考资料: 1.博客1:https://blog.csdn.net/zhou1021jian/article/details/71531699 2.博客2:https://blog.csdn.net/ ...

  2. linux多进/线程编程(5)——进程间通信之mmap

    参考资料: 1.博客1:https://www.jianshu.com/p/755338d11865 mmap:一种内存映射文件的方法 memory map 父子进程和无亲缘关系的进程,都可以将自身用 ...

  3. linux多进/线程编程(2)—— fork函数和进程间“共享”数据

    参考: 1.博客1:https://www.pianshen.com/article/4305691855/ fork:在原进程的基础上"分叉"出一个子进程,即创建一个子进程. N ...

  4. linux多进/线程编程(3)——wait、waitpid函数和孤儿、僵尸进程

    当使用fork创建多个进程后,需要解决子进程回收的问题.wait和waitpid函数就是做这个工作的. 假设子进程没有合理的回收,可能会带来两个问题: 1.孤儿进程(父进程挂了,子进程活着),孤儿进程 ...

  5. linux多进/线程编程(1)—— 基础概念(PCB、MMU、进程状态)

    学习大概就是不断迭代.重构的过程,不复习的学习是不负责任的,亦是无用的. 本系列博客主要作为个人记录,主要是贴图和代码,不做详细解释,以后有时间可能会重写:从下一篇开始上代码,代码可以运行是对自己的最 ...

  6. 《Linux多线程服务端编程》笔记——线程同步精要

    并发编程基本模型 message passing和shared memory. 线程同步的四项原则 尽量最低限度地共享对象,减少需要同步的场合.如果确实需要,优先考虑共享 immutable 对象. ...

  7. Linux线程编程之信号处理

    前言 Linux多线程环境中的信号处理不同于进程的信号处理.一方面线程间信号处理函数的共享性使得信号处理更为复杂,另一方面普通异步信号又可转换为同步方式来简化处理. 本文首先介绍信号处理在进程中和线程 ...

  8. linux网络编程之进程间通信介绍

    从今天起,开始学习进程间通信相关的东东,关于socket的编程先告一段落了,在学习进程间通信之前,首先先要了解一些概念,所以,这次不开始真正的代码编写,先纯理论,理解了为之后的更深入的学习可以打下良好 ...

  9. 一、智能指针及线程同步总结------linux多线程服务端编程

    更新2.0 二.多线程及服务器编程总结------linux多线程服务端编程 https://www.cnblogs.com/l2017/p/11335609.html 三.分布式编程总结------ ...

随机推荐

  1. css中设置背景图片适应屏幕

    以body为例 body{ background: url(../img/jld.png) no-repeat center center fixed; -webkit-background-size ...

  2. linux实时监控并实时备份数据(rsync)

    目录 一:rsync实时监控备份流程 1.安装rsync(服务端 与 客服端)守护进程模式 2.修改配置文件(服务端) 3.解析配置内容 4.创建系统用户 5.创建密码文件 6.授权(必须授权为600 ...

  3. linux挂载windows nfs

    1.win下创建nfs文件夹并共享 2.登陆linux,执行 yum 3.创建挂载点 4.挂载win nfs 5./etc/fstab添加永久挂载 6.查看挂载磁盘,此时windows盘已落在linu ...

  4. l线程池抓取lianjia

    1. 线程池 的应用 from multiprocessing.dummy import Pool import requests from lxml import etree url="h ...

  5. django入门 02 初探app、view、url、templates、static

    创建APP命令 python manage.py startapp myapp app组成介绍 如上图,在终端中展示树状结构-- windows为 tree /f macOS为 tree 注册APP ...

  6. Nginx网络压缩 CSS压缩 图片压缩 JSON压缩

    一.序言 使用Nginx作为web应用服务时,会代理如下常见文件:js.css.JSON.图片等,本文提供基于Nginx内置的压缩技术,提供网络请求响应速度的解决方案. 1.网络压缩原理 网络压缩的原 ...

  7. 多种方式告诉你如何计算DM同步数据到TiDB的延时时间

    背景 用户在做技术选型的过程中,总是会对一些数据指标比较关心,特别是在和竞品相比较的时候,更加需要一些有说服力的数据.基于MySQL开发的项目在迁移到TiDB的时候,使用DM同步数据是必不可少的一个环 ...

  8. Mysql一个主一备

    Mysql主从复制 -- 一主一备 主从复制原理: Mysql的主从复制是mysql本身自带的一个功能,不需要额外的第三方软件可以实现,其复制功能并不是copy文件实现的,而是借助binlog日志文件 ...

  9. JS 解构赋值

    感谢原文作者:小火柴的蓝色理想 原文链接:https://www.cnblogs.com/xiaohuochai/p/7243166.html 介绍 解构赋值语法是一种 Javascript ES6引 ...

  10. 乐动ld06激光雷达sdk改bug记录分享

    前言: 工作中,有使用过乐动ld06款激光雷达,此款雷达将常规雷达的转动的电机部分内置于自己的保护罩内,减少了雷达本身转动积灰等其他外界影响,探测半径是12m,是一款不错的雷达. 不过今天的主要内容不 ...