当前位置: 首页 > backend >正文

Linux_3:进程间通信

IPC

1.什么是IPC?Inter Process Communication

2.进程间通信常用的几种方式

        1,管道通信:有名管道,无名管道

        2,信号- 系统开销小

        3,消息队列-内核的链表

        4,信号量-计数器

        5,共享内存

        6,内存映射

        7,套接字

无名管道

管道的概念

1.本质

内核缓冲区

伪文件-不占用磁盘空间

2特点:

两部分: 读端,写端,对应两个文件描述符

数据写端流入,读端流出

操作管理的进程被销毁之后,管道自动被释放

管道默认是阻塞的

管道的原理

1.内部实现方式:

队列-环形队列

特点:先进先出

2.缓冲区大小

默认4K,大小会根据实际情况做适当调整

管道的局限性

1.队列: 数据只能读取一次,不能重复读取

2.半双工:

单工:遥控器

半双工:对讲机

创建匿名管道

int pipe(int fd[2])

fd‐传出参数:

        fd[0]‐读端

        fd[1]‐写端

返回值:

        0:成功

        ‐1:创建失败

父子进程使用管道通信

实现 ps aux | grep "bash"

数据重定向:dup2

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>int main()
{int ret;int fd[2];ret = pipe(fd);if(ret == -1){printf("pipe creat failed\n");exit(1);}printf("pipe creat success!\n");printf("fd[0] is %d\n",fd[0]);printf("fd[1] is %d\n",fd[1]);close(fd[0]);close(fd[1]);return 0;
}
~         

注012是标准输入输出和报错

       int dup2(int oldfd, int newfd);//新段指向旧端

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>int main()
{pid_t pid;int ret;int fd[2];ret = pipe(fd);if(ret == -1){printf("pipe creat failed\n");exit(1);}printf("pipe creat success!\n");pid = fork();if(pid == -1){printf("fork failed\n");exit(1);}if(pid > 0){close(fd[0]);dup2(fd[1],STDOUT_FILENO);execlp("ps","ps","aux",NULL);perror("excelp");exit(1);}else if (pid == 0){close(fd[1]);dup2(fd[0],STDIN_FILENO);execlp("grep","grep","bash","--color=auto",NULL);}return 0;
}

单个进程也可以使用管道
父子进程在使用管道的时候,父进程写的时候要关闭读,子进程读的时候要关闭写 

管道的读写行为

1.读操作

        1)有数据:read(fd[0]) 正常读,返回读出的字节数

        2)无数据:

                写端被全部关闭,read返回0,相当于读文件到了尾部

                没有全部关闭,read阻塞

2.写操作

        1)读端全部关闭:

                管道破裂,进程被终止

                内核给当前进程发送信号SIGPIPE-13,默认处理动作

        2)读端没全部关闭:

                缓冲区写满了,write阻塞

                缓冲区没满,write继续写,直到写满,阻塞

3.如何设置非阻塞?

1)默认读写两端都阻塞

2)设置读端为非阻塞pipe(fd):

        fcntl-变参函数:复制文件描述符-dup;修改文件属性-open的时候对应flag属性

        设置方法

//获取原来的flags 

int flags = fcntl(fd[0],F+GETFL); 

//设置新的flags 

flag |=O_NONBLOCK; 

fcntl(fd[0],F_SETFL,flags); 

fcntl(fd[0],F_SETFL,flags); 

查看管道缓冲区大小

命令:

ulimit -a

fpathconf

  long fpathconf(int fd, int name);

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>int main()
{int ret;int fd[2];ret = pipe(fd);if(ret == -1){printf("pipe creat failed\n");exit(1);}printf("pipe creat success!\n");long size = fpathconf(fd[0],_PC_PIPE_BUF);printf("size id %ld\n",size);printf("fd[0] is %d\n",fd[0]);printf("fd[1] is %d\n",fd[1]);close(fd[0]);close(fd[1]);return 0;
}

有名管道

函数形式:int mkfifo(const char \*filename,mode_t mode);

功能:创建管道文件

参数:管道文件文件名,权限,创建的文件权限仍然和umask有关系。

返回值:创建成功返回0,创建失败返回-1。

特点

        有名管道

        在磁盘上有这样一个文件 ls -l ->p

        也是一个伪文件,在磁盘大小永久为0

        数据存在内核中有一个对应的缓冲区

        半双工通信方式

使用场景

没有血缘关系的进程间通信

创建方式

命令:mkfifo 管道名

函数:mkfifo()

 int mkfifo(const char *pathname, mode_t mode);

fifo文件可以使用io函数进程操作

open/close,read/write

不能执行lseek操作

读函数

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>int main()
{int ret;int fd;int nread;char readBuff[50] = {0};ret = mkfifo("/home/u/process/myfifo",0777);if(ret == -1){return -1;}printf("creat file success!\n");fd = open("./myfifo",O_RDONLY);if(fd < 0){return -1;}printf("open file success!\n");nread = read(fd,readBuff,50);printf("read %d byte from fifo :%s\n",nread,readBuff);close(fd);return 0;
}

写程序

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>int main()
{int fd;char *str = "hello world!";fd = open("./myfifo",O_WRONLY);if(fd < 0){return -1;}printf("open file success!\n");write(fd,str,strlen(str));close(fd);return 0;
}
~      

http://www.xdnf.cn/news/15215.html

相关文章:

  • (六)复习(OutBox Message)
  • 游戏的程序员会不会偷偷改自己账号的数据?
  • C++迭代器失效
  • 数据结构 顺序表(3)---顺序表的应用
  • 计算机基础:内存模型
  • 深入理解JVM的垃圾收集(GC)机制
  • 【U-Boot】Shell指令
  • 今日行情明日机会——20250711
  • 运行ssh -T git@github.com报错
  • 【工具变量】全国省市区县土地出让结果公告数据(2000-2024年)
  • 限流算法
  • time_wait状态分析
  • 数据库大文件损坏后,数据恢复操作(记录)
  • windows exe爬虫:exe抓包
  • 开源“具身大脑” 实现不同机器人群体协作-RoboBrain
  • 电力分析仪的“双语对话”:CCLinkIE与Modbus TCP的无缝连接
  • ParaCAD 笔记 png 图纸标注数据集
  • 小木的机器学习日记——KNN
  • Flowable 使用遇到问题
  • 深度学习×第8卷:优化器与训练流程进阶——她开始跑起来,学着一次次修正自己
  • 大模型及agent开发6 OpenAI Assistant API 高阶应用 - 流式输出功能
  • pytorch的介绍以及张量的创建
  • css——width: fit-content 宽度、自适应
  • Express + @vladmandic/face-api + mySql 实现人脸识别
  • 深度学习篇---松科TPU部署代码分析
  • excel如何只保留前几行
  • JAVA ---Excel高效导入(去重1000万数据对比)
  • 【Qt 学习之路】Qt Android开发环境搭建:Ubuntu的Vmware虚拟机中的踩坑实录
  • 国产AI linux 桌面安装详解 (deepin 深度)
  • MinIO配置项速查表【五】