linux--管道

news2024/11/17 6:34:57

这里写自定义目录标题

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

基本概念

进程间存在天然的壁垒,进程间通信(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二个可执行文件
在这里插入图片描述

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

无名管道

这个比较简单直接上代码

#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/136516.html

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

相关文章

MyISAM 引擎和 InnoDB 引擎中索引存储的区别

一、MyISAM 引擎下的索引 MyISAM 存储引擎不支持行级锁&#xff0c;只有表级锁&#xff1b;不支持事务&#xff0c;也不支持外键&#xff0c;主要面向 OLAP 应用&#xff0c;是 MySQL 数据库5.5.8 版本之前默认的存储引擎&#xff0c;MyISAM 适用于不需要关心事务&#xff0c;…

实时即未来,大数据项目车联网之原始数据实时ETL任务HBase调优【九】

1. 原始数据实时ETL任务HBase调优 1.1 数据写入hbase优化 上一节写入数据,一条条数据put到表中,对于大量数据的写入,效率极低,因此针对此项进行优化 使用hbase客户端写缓存进行批量写入数据到hbase中 hbase客户端写缓存对象:BufferedMutator hbase的每一次put操作写入数据…

CSS权威指南(二)选择符

1.样式的基本规则 CSS的一个核心优势就是可以为文档中某种种类的元素全部应用相同的样式规则。CSS样式便于修改和编辑&#xff0c;而且能应用到指定的所有文本元素上。 &#xff08;1&#xff09;元素选择符 即直接使用元素的名称进行选择&#xff0c;类似于p{ font-size:10px…

Lc.152 乘积最大子数组

题目链接1 前言翻译成大白话&#xff1a;就是找一个数组&#xff0c;其连续子数组的乘积最大值。2 算法思路&#xff1a;一般求最值的问题首选动态规划。这道题与[LC.53 最大子序和]很类似。我们假设状态转移方程为:它表示以第 i 个元素结尾乘积最大子数组的乘积可是在这里&…

异步通信技术AJAX | AJAX实现省市联动、AJAX跨域问题

目录 一&#xff1a;异步通信技术AJAX | 快速搞定AJAX&#xff08;第四篇&#xff09; 1、AJAX实现省市联动 2、超链接、form表单和JS代码跨域 3、AJAX跨域问题 &#xff08;1&#xff09;测试Ajax跨域访问 &#xff08;2&#xff09;同源 & 不同源 &#xff08;3&a…

可以通过哪些方式了解量化接口level2?

可以通过哪些方式了解量化接口level2&#xff1f;大家可以去百查看关于量化交易接口的信息&#xff0c;根据小编对市场上大多数的level2接口了解发现既有要收费的也有免费的&#xff0c;一般来说第三方软件公司提供的都是收费的居多&#xff0c;一些正规券商提供的就是免费的居…

一文读懂自动驾驶汽车:软硬结合 造就未来出行体验(下篇)

在上篇&#xff0c;我们回顾了自动驾驶汽车的发展历史&#xff0c;介绍了自动驾驶汽车的工作原理。得益于 AI 技术的突破&#xff0c;自动驾驶汽车飞速发展&#xff0c;运算速度也从 2007 年的 230 FLOPS 跃升至 2022 年的 254 TOPS&#xff0c;向软件定义汽车发展。现在&#…

数据结构-考研难点代码突破 (C++实现有向无环图的拓扑排序)

文章目录1. AOE网2. 拓扑排序C代码1. AOE网 AOV网∶若用DAG 图&#xff08;有向无环图&#xff09;表示一个工程&#xff0c;其顶点表示活动&#xff0c;用有向边<Vi&#xff0c;Vj>表示活动 Vi必须先于活动Vj进行的这样一种关系&#xff0c;则将这种有向图称为顶点表示…

基于主从博弈的智能小区代理商定价策略及电动汽车充电管理(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

C语言贪吃蛇大作战

C语言贪吃蛇大作战 贪吃蛇大作战 1997 年&#xff0c;诺基亚公司发布了贪吃蛇游戏&#xff0c;并将其内置于诺基亚 6110 手机中&#xff0c;使这款游戏迅速风靡全球&#xff0c;成为一代经典。一般的观点认为&#xff0c;贪吃蛇是手机游戏的鼻祖。 与传统单人贪吃蛇不同的是&…

【时间之外】系统管人,能行?(冷眼旁观连载之一)

目录 写作初心 在用工具 某微 某道 某书 工具痛点 某微痛点 某道痛点 某书痛点 总结一下&#xff1a;功能复杂 2023年观察计划 最大痛点 效果跟踪 未完待续 写作初心 2022年应该是这一生中值得纪念的一年&#xff0c;疫情封控自不必说&#xff0c;对于个人而言&a…

traefik gateway api

背景 在使用istio后开始考虑网关了&#xff0c;istio已经有自己的网关&#xff0c;为什么还要另外找一个别的网关&#xff0c;参考了好几个文章大致结论是&#xff0c;istio的网关功能不够强大&#xff0c;下图红色的部分是istio网关暂时缺失的&#xff0c;所以我的结论是在is…

Monorepo 下 Git 工作流的最佳实践

作者&#xff1a;林宜丙 背景 没有哪一种 Git 工作流是银弹&#xff0c;合适的 Git 工作流往往取决于项目的代码规模、协作人数、应用场景等&#xff1b;本次分享先从适合小型 Monorepo 的 Feature branch 工作流开始分享&#xff0c;接着分享适用于中大型 Monorepo 的 Trunk…

头歌:Ping客户端创建原始套接字(底部附全关完整答案)

头歌实践教学平台 (educoder.net)为Ping客户端创建一个原始类型的套接字原始套接字套接字&#xff08;socket&#xff09;是一个抽象层网络应用程序可以通过它发送或接收数据&#xff0c;可对其进行像文件一样的打开、读写和关闭等操作。套接字允许应用程序将I/O插入到网络中&a…

<C++>二叉树进阶

文章目录为什么要学这一节1. 二叉搜索树1.1 二叉搜索树概念1.2 二叉搜索树操作1.3 二叉搜索树的实现1.4 二叉搜索树的应用1.5 二叉搜索树的性能分析2. 经典题目2.1 最近公共祖先2.2 从前序与中序遍历序列构造二叉树2.3 二叉树的前序遍历&#xff08;非递归&#xff09;为什么要…

计算机组成原理复习:数据的表示和运算

计算机组成原理复习&#xff1a;数据的表示和运算2. 数据的表示和运算2.1 数制与编码2.1.1 数制&#xff1a;进位计数制及其相互转换2.1.2 编码&#xff1a;数值数据的编码与表示2.1.2.1 逻辑型数据2.1.2.2 字符型数据 之 ASCII码2.1.2.3 数值型数据 之 BCD码2.1.3 校验码——奇…

Part类 -- 上传文件

Part类 -- 上传文件一、核心方法1.1 HttpServletRequest 类方法1.2 Part 类方法二、代码示例前端搭配 form 表单&#xff1a;form input type “file”&#xff0c;允许通过浏览器选中一个文件上传给服务器。 Servlet 就支持处理这种上传文件的请求&#xff0c;把这个请求到的文…

安科瑞智能操控无线测温装置在江苏某化工产业园项目的应用

安科瑞 李亚俊 1 概述 江苏富强新材料有限公司是中国企业500强——山东金岭集团在江苏淮安盐化新材料产业园区投资设立的盐化工企业。公司将利用淮安丰富的盐矿资源和优越的发展环境&#xff0c;投资200亿元&#xff0c;建设120万吨/年离子膜烧碱项目、70万吨/年甲烷氯化物项…

vue新春游戏-拼手速抢车票小游戏,学习玩乐两不误,春节小游戏,新年小游戏

ue新春游戏-拼手速抢车票&#xff0c;老规矩&#xff0c;体验地址&#xff1a;http://game.pkec.net/word-ticket/。 写这个主要是前几天群里运营老师说咋没人写抢车票的&#xff0c;再加上我上一篇文章上了掘金一周&#xff0c;听说多上几次有证书&#xff0c;我还没搞到过掘金…

Go语言 函数传递:值传递 和 虚假的 “引用传递”

前言 其实从变量本身来说&#xff0c;go只有值传递&#xff0c;函数内的修改不会影响函数外。但有一种特例是指针&#xff0c;go可以传指针给函数&#xff0c;指针指向申请出来的实际内存&#xff0c;也就是保存元素的内存&#xff0c; 这样在函数内的修改&#xff0c;可以影响…