linux C--管道

news2024/12/27 16:12:50

这里写自定义目录标题

  • 基本概念
  • 管道特征
  • 编写模型
    • 有名管道模型
      • 示例demo
        • write.c
        • read.c
      • 结果记录
      • 笔记1
    • 无名管道

基本概念

进程间存在天然的壁垒,进程间通信(Interperocess Communication,IPC)是指二个或者多个进程之间进行数据交换的过程

管道特征

管道是进程间通讯的一种常用方法。管道分为有名管道fifo无名管道pipe

  • 管道创建后是单向的,一端是写,一端是读(如果需要想双向,没办法创建二根管道)
  • 管道有大小,linux内核对每个管道的大小限制在4096字节
  • 无名管道一般用在父子线程间通讯
  • 有名管道一般用在进程和不同线程之间通讯
  • 管道是阻塞的,读取管道过程中一直处于阻塞的状态
  • 管道在被读取前,只能写入一次,多次写入是无效的

编写模型

有名管道模型

步骤进程A进程B步骤
1.创建管道mkfifo
2.打开管道openopen1.打开管道
3.读写管道write/readwrite/read2.读写管道
4.关闭管道closeclose3.关闭管道
5.删除管道unlink

示例demo

注意:有名管道需要依靠文件来传递,我们再/tmp目录下去建文件,因为tmp目录是临时目录,开机就清除了

write.c

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>

#define FIFO_FILE "/tmp/fifo"

int main(void){
    printf("创建管道...\n");
    if(mkfifo(FIFO_FILE,0666) == -1){
        perror("mkfifo");
        return -1;    
    }
    
    printf("打开管道...\n");
    int fd = open(FIFO_FILE,O_WRONLY);
    if(fd == -1){
        perror("open");
        return -1;
    }
    
    printf("发送数据...\n");
    for(;;){
        printf(">");
        char buf[1024];
        gets(buf);
        if(!strcmp(buf,"!"))
            break;
        if(write(fd,buf,(strlen(buf)+1)))  * sizeof(buf[0]) == -1){
            perror("write");
            return -1;        
        }                     
    }
    
    printf("关闭管道...\n");
    if(close(fd) == -1){
        perror("close");
        return -1;    
    }
    
    printf("删除管道...\n");
    if(unlink(FIFO_FILE) == -1){
        perror("unlink");
        return -1;    
    }
    
    printf("大功告成!\n");
    return 0;
}

read.c

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>

#define FIFO_FILE "/tmp/fifo"

int main(void){
    printf("打开管道...\n");
    int fd = open (FIFO_FILE,O_RDONLY);
    if(fd == -1){
        perror("open");
        return -1;
    }
    
    printf("接收数据...\n");
    for(;;){
        char buf[1024];
        size_t rb = read(fd,buf,sizeof(buf));
        if(rb == -1){
            perror("read");
            return -1;
        }    
        
        if(!rb)
            break;
        printf("< %s\n",buf);
    }
    
    printf("关闭管道...\n");
    if(close(fd) == -1){
        perror("close");
        return -1;
    }
    
    printf("大功告成!\n");
    return 0;

结果记录

我们先编译一下
在这里插入图片描述
生成writeread二个可执行文件
在这里插入图片描述

我们测试一下管道在这里插入图片描述
最后记得删除管道,不然再创建的时候会有一些莫名错误!

笔记1

我们再尝试一下,打开管道的命令在linux中也是一个阻塞的操作我们修改一下write.c的代码

 //服务信息
    while(1)
    {
        char buffer[128]={0};

        //打开管道文件
        printf("打开管道中...\r\n");
        fd=open(FIFO,O_RDONLY);
        if(fd<0) {
            printf("打开管道:失败!\r\n");
            return(-2);
        }
        else {
            printf("打开管道:成功!\r\n");
        }

        //输出标识词
        printf("Recv Data:");
        //读取管道数据
        ssize_t s=read(fd,buffer,sizeof(buffer)-1);


        if(s>0) {
            buffer[s]=0;
            printf("%s\r\n",buffer);
        }

        if(close(fd) == -1){
            printf("close false!\r\n");
            return -1;
        }
    }

记录一下运行的结果
在这里插入图片描述
发现open管道其实是阻塞了线程,这些阻塞的地方我们称为焦点,理解这些焦点对我们编写代码很重要。
我们再看一下管道的文件,在tmp临时文件夹中我们创建的管道文件。
在这里插入图片描述

无名管道

这个比较简单直接上代码

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>

int main(void){
    printf("父进程:创建管道...\n");
    int pipefd[2];
    
    if(pipe(pipefd) == -1){
        perror("pipe");
        return -1;    
    }
    
    printf("父进程:创建进程...\n");
    pid_t pid = fork();
    if(pid == -1){
        perror("fork");
        return -2;    
    }
    
    /* fork之后就多了一个子进程,父进程和子进程在宏观
    上是并发的关系,这样就理解为2个mian函数一起运行了
    之后我们用if判断语句来做分支处理,这样实现pipe的
    通讯*/
    
    
    if(pid == 0){
        printf("子进程:关闭写端...\n");
        close(pipefd[1]);
        printf("子进程:接收数据...\n");
        for(;;){
            char buf[1024];
            ssize_t rb = read(pipefd[0],buf,sizeof(buf));
            if(rb == -1){
                perror("read");
                return -1;            
            }
            else if(rb == 0){
                //注意:如果读到的返回结果是0,说明pipe被关闭了,这个时候结束
                break;            
            } 
            
            puts(buf);  //数据打印出来            
        }
        printf("子进程:关闭读端...\n");
        close(pipefd[0]);
        printf("子进程:大功告成!\n");
    }
    
    printf("父进程:关闭读端...\n");
    close(pipefd[0]);
    printf("父进程:发送数据...\n");
    for(;;){
        char buf[1024];
        if(!strcmp(buf,"!")) {
            break;        
        }   
        
        if(write(pipefd[1],buf,strlen(buf)+1) == -1){
            perror("write");
            return -1;        
        }
    }
    printf("父进程:关闭写端...\n");
    close(pipefd[1]);
    if(wait(0) == -1){
        perror("wait");
        return -1;    
    }
    
    printf("父进程:大功告成!\n");
    return 0;
}

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

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

相关文章

Tomcat安装及使用

1.下载 Tomcat官网 选择系统 2.解压 解压到没有中文路径的文件夹中,解压路径会在配置环境变量时用到 3.配置环境变量 在电脑点击鼠标右键->点击属性>点击高级系统设置->点击环境变量->新建系统变量 1.新建系统变量 变量名为CATALINA_HOME&#xff0c;变…

【unity3D】DoTween动画插件(下)

&#x1f497; 未来的游戏开发程序媛&#xff0c;现在的努力学习菜鸡 &#x1f4a6;本专栏是我关于游戏开发的学习笔记 &#x1f236;本篇是unity的DoTween动画插件可视化编辑 DoTween动画插件&#xff08;可视化编辑&#xff09;DOTween AnimationDoTween Path路径编辑器Scene…

【Linux】Linux编辑器—vim使用

目录1.vim的基本概念2.vim基本操作3.vim命令模式命令集4.vim末行模式命令集5.简单vim配置6.使用sudo提权为什么要学习vim&#xff1f; “在 Linux 系统中一切都是文件&#xff0c;而配置一个服务就是在修改其配置文件的参数”。 而且在日常工作中大家也肯定免不了要编写文档&am…

学习C语言笔记:浮点类型float、double和long double

浮点类型能表示包括小数在内更大范围的数。浮点数的表示类似于科学计数法&#xff08;即用小数乘以10的幂来表示数字&#xff09;。该记数系统常用于表示非常大或非常小的数。 float C语言规定&#xff0c;float类型必须至少能表示6位有效数字&#xff0c;且取值范围至少是~…

【阶段二】Python数据分析Pandas工具使用03篇:数据预处理:多表合并与连接

本篇的思维导图: 数据预处理:多表合并与连接 将表结构相同(即变量个数和变量类型均相同)的多张表纵向合并到一张长表中,或者将多张表的变量水平扩展到一张宽表中。 需要注意的是,对于多表之间的纵向合并,则必须确保多表的列数和数据类型一致;对于多表之间的水平扩展,…

电子邮件帐户受损报告,请查收!

我们收到有关恶意访问 Ambire Wallet 电子邮件帐户的报告。 所有这些账户都是用在 CoinMarketCap/Ledger/其他黑客事件中被破坏的电子邮件地址注册的。 我们的内部调查显示&#xff0c;Ambire 的内部系统没有被泄露。我们调查的所有受影响的账户都是因为他们的电子邮件被泄露&…

FOFA(一): FOFA入门

文章目录一、FOFA是什么二、Fafo的使用1. 用户注册2. 一般使用3. 高级用法三、界面解释一般检索结果ip聚合:统计:以ip为单位的资产数据统计:四、API参考一、FOFA是什么 部署在互联网上的网络设备资产信息搜索引擎。旨在尽可能多的对全球IT设备资产进行信息收集、 漏洞扫描&…

java知识图谱+Java语言特点+常用dos命令+Java程序总结

java知识图谱高级语言Java语言特点注释单行注释 //多行注释/* */作用&#xff1a;1.对程序的编写进行解释说明&#xff0c;增强可读性2.调试所写代码单行/多行注释不参与编译&#xff1b;多行注释不可嵌套使用文档注释&#xff08;Java特有&#xff09;/** */注释内容可被JDK提…

系统治理 体系规划新型数据安全防护体系

声明 本文是学习2022中国工业数据勒索形势分析报告. 下载地址 http://github5.com/view/55028而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 工业数据勒索应急响应事件攻击者分析 应急响应事件攻击者分析以2022年1-9月所有工业数据勒索应急数据为支撑…

Hadoop HDFS

Hadoop HDFS分布式文件系统分布式文件系统的优点HDFS(Hadoop分布式文件系统)应用常见hdfs集群存储机制元数据管理namespace分布式文件系统 既然我们要学习hdfs那就不能不提分布式文件系统 文件系统是一种存储和组织数据的方法&#xff0c;实现了数据的存储、分级组织、访问和…

Linux DNS 解析与配置 nslookup使用 与 /etc/resolv.conf文件的配置

Linux DNS 解析与配置 序 当我接收到一批新的服务器时&#xff0c;尝试连接外网&#xff0c;比如访问百度的首页&#xff1a; curl www.baidu.com发现报错&#xff0c;不能解析正确的主机名。这个其实就是主机在解析主机名时没能正确发现对应的主机的 ip。当我们使用类似于域…

华为交换机配置笔记

交换机(Switch)是一种用于电信号转发的网络设备,它可以为接入交换机的任意两个网络节点提供独享的电信号通路,最常见的交换机是以太网交换机,其他常见的还有电话语音交换机、光纤交换机等,交换机是集线器的升级替代产品,理论上讲交换机就是按照通信两端传输信息的需求,将需要的…

ONES 入选极客公园「2022 中国创新力量 50 」榜单

极客公园调研发现&#xff0c;2022 年是企业服务的「双杀」转折点&#xff1a;内部造血的难度升级&#xff0c;外部输血的可能性降低。为了表彰逆流而上的企服公司&#xff0c;极客公园对其给予了重点鼓励和点评。其中&#xff0c;企业级研发管理平台 ONES 入选了极客公园 2022…

vue js游戏,抗疫小游戏,抗疫的汤圆,仅以此小游戏献给所有为抗击疫情做出贡献的人

vue js游戏&#xff0c;抗疫小游戏&#xff0c;抗疫的汤圆&#xff0c;仅以此小游戏献给所有为抗击疫情做出贡献的人 完整代码下载地址&#xff1a;vue js游戏&#xff0c;抗疫小游戏&#xff0c;抗疫的汤圆 建议在pc上使用Chrome浏览器进行访问&#xff0c;如果只能手机玩&a…

还不快收藏起来!何恺明全网最全论文合集

原创/文 BFT机器人 人物简介 何恺明&#xff0c;Facebook AI Research (FAIR) 的一名科学家&#xff0c;研究领域包括计算机视觉和深度学习&#xff0c;并且在计算机视觉和深度学习方面发表了众多极具影响力的论文。 他发表的论文中&#xff0c;有关深度残差网络 (ResNets) 的…

当下的零售新进化,同以往的电商时代还是有着很多区别的

一场数字化的浪潮&#xff0c;正在各行各业深刻上演着。在零售领域&#xff0c;亦不例外。以往&#xff0c;提及零售&#xff0c;我们更多地想到的是&#xff0c;各式各样的电商平台&#xff0c;我们看到的是&#xff0c;各式各样的电商模式&#xff1b;现在&#xff0c;提及零…

学习一下如何使用python实现一个超级卡哇伊的五角星吧

Hello呀朋友们~ 今天实在想不出要写啥了&#xff0c;但是前两天有朋友让我写一个五角星&#xff0c;这个好说呀&#xff0c;必须安排的妥妥当当的&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; 在这里我就不多说了&#xff0c;这个也挺简单的&#xff0c;那…

新代机床联网

一、设备信息确认 1、确认型号 数控面板拍照确认&#xff1a; 此系统为&#xff1a;6TA 2、确认通讯接口 1、数控面板的后面 2、其他位置 其他位置一般是前面两个位置用网线引出来后做的网口母头&#xff0c;常见在机床数控面板侧面&#xff0c;机床电器柜后面等等。 3、…

Kubernetes知识扫盲

1. Kubernetes介绍 1.1 应用部署方式演变 在部署应用程序的方式上&#xff0c;主要经历了三个时代&#xff1a; 传统部署&#xff1a;互联网早期&#xff0c;会直接将应用程序部署在物理机上 优点&#xff1a;简单&#xff0c;不需要其它技术的参与 缺点&#xff1a;不能为应…

SQL数据库—事务(ACID特性、数据库恢复技术)

各位朋友大家好&#xff0c;博主新创立了一个公众号《自学编程村》哈&#xff0c;感兴趣的可以也关注关注捏~~ 【简介】 它是由村长发起&#xff0c;然后邀请了一些小伙伴来作为自己的嘉宾&#xff0c;不定时的为大家分享学习、生活、信息。他们中间&#xff0c;有来自中国科学…