<Linux开发> linux应用开发-之-进程通信之管道例程

news2024/11/8 18:00:14

一、简介

所谓管道,是指用于连接一个读进程和一个写进程,以实现它们之间通信的共享文件,又称 pipe 文件。

向管道(共享文件)提供输入的发送进程(即写进程),以字符流形式将大量的数据送入管道;而接收管道输出的接收进程(即读进程),可从管道中接收数据。由于发送进程和接收进程是利用管道进行通信的,故又称管道通信。

为了协调双方的通信,管道通信机制必须提供以下3 方面的协调能力。

(1)互斥。当一个进程正在对 pipe 进行读/写操作时,另一个进程必须等待。
(2)同步。当写(输入)进程把一定数量(如4KB)数据写入 pipe 后,便去睡眠等待,直到读(输出)进程取走数据后,再把它唤醒。当读进程读到一空 pipe 时,也应睡眠等待,直至写进程将数据写入管道后,才将它唤醒。
(3)对方是否存在。只有确定对方已存在时,才能进行通信。

二、环境搭建

本次测试pipe通信的应用例程是运行在ubuntu pc上的;当然也是可以运行在linux开发板 或相关linux设备上的。
开发环境无特别要求。

三、例程代码

本次代码会使用单独的一个c文件用来pipe进程代码,使用子进程写入数据到Pipe中,并通过主进程读取pipe中的数据并打印。
创建.c文件,并输入一下内容:

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


#define INPUT 1
#define OUTPUT 0

void main()
{
    int Upipe[2];                   //用以管道描述符
    pid_t pid;                      //用于子进程pid创建
    char buf[256];                  //用于存放接收管道的数据
    int returned_count;             //读取管道的返回值状态
    int i =0;                       //计数用
    char Sendbuf[256];              //用于存放发送管道的数据
    /*创建无名管道*/
    //pipe(Upipe);
    if (pipe(Upipe) == -1) {        //创建管道
        perror("pipe");             //终端输出
        exit(EXIT_FAILURE);         //退出
    }

    /*创建子进程*/
    if((pid = fork()) == -1){       //创建子进程
        printf("Error in fork\n");  //终端输出
        exit(1);                    //退出
    }

    if(pid == 0) {
        while(1){   /*子进程运行内容*/
            printf("in the spawned child process ... \n");
            sprintf(Sendbuf,"TEST data:%d \n",i);               //组合需要发送的数据内容
            if(i%2)                                             //计数值对2取余数
            {
                close(Upipe[OUTPUT]);                            //管壁输入
                write(Upipe[INPUT],Sendbuf, strlen(Sendbuf));
            }
            
            i++;
            if(i>100000)
            {
                i=0;
            }
            sleep(1);
        }
    } else {
        while(1){ /*主进程运行内容*/
            printf("in the spawned parent process ... \n");
            close(Upipe[INPUT]);
            returned_count = read(Upipe[OUTPUT],buf, sizeof(buf));
            printf("%d bytes of data received from spawned prcess :%s \n",returned_count, buf);
            sleep(1);
        }
    }

}

四、编译运行

1、编译命令:

gcc  -g -o UnnamedPipes  UnnamedPipes.c

2、运行命令

./UnnamedPipes

3、运行输出效果如下图:
在这里插入图片描述

五、总结

管道写操作流程如下:
写之前先锁定内存。
获取可写的缓冲区,若可写则循环写。
若不可写,则唤醒读进程,同时写进程进行休眠,让出 CPU。

读的操作很简单,操作如下:
读之前先锁定内存。
从缓冲区中获取数据页,把页中数据拷贝到用户缓冲区中。
数据全部被读完,则发送信号唤醒写进程,同时读进程让出 CPU 进行休眠。

管道也称无名管道,是 UNIX 系统中进程间通信(IPC)中的一种。
管道由于是无名管道,因此只能在有亲缘关系的进程间使用。
管道不是普通的文件,它是基于内存的。
管道属于半双工,数据只能从一方流向另一方,也即数据只能从一端写,从另一端读。
管道中读数据是一次性的操作,数据读取后就会释放空间,让出空间供更多的数据写。
管道写数据遵循先入先出的原则。

注意,在这个例子中,为什么这两个进程都关闭它所不需的管道端呢?

这是因为写进程完全关闭管道端时,文件结束的条件被正确地传递给读进程。而读进程完全关闭管道端时,写进程无需等待继续写数据。

阻塞读和写分别成为对空和满管道的默认操作,这些默认操作也可以改变,这就需要调用 fcntl() 系统调用,对管道文件描述符设置 O_NONBLOCK 标志可以忽略默认操作:

#include <fcntl.h>

fcntl(fd,F_SETFL,O_NONBlOCK);

管道作为进程通信的一种方法,在实际开发中也是经常会使用的。上述例程是一个简单的运用例子。读者自行参考学习使用。
欢迎交流…

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

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

相关文章

Windows串口出厂测试工具与使用说明

WCHUsbSerTest是一款用于WCH USB转串口系列产品出厂测试的工具软件&#xff0c;方便用户对产品进行批量化功能测试。该软件支持以下特性&#xff1a; 支持设备热插拔检测&#xff0c;插入自动测试。支持两种测试模式&#xff1a;1个设备自测、2个设备互相连接测试。支持多种串…

VMware Horizon 8 2303 - 虚拟桌面基础架构 (VDI) 和应用软件

请访问原文链接&#xff1a;https://sysin.org/blog/vmware-horizon-8/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&#xff1a;sysin.org Version2303DocumentationRelease NotesRelease Date2023-03-30 虚拟桌面基础架构 (VDI) 和应用软件 VMw…

chagpt中文镜像版-ChatGPT工具下载

ChatGPT工具下载 ChatGPT是由OpenAI公司开发的预训练语言模型&#xff0c;目前已经开源并在GitHub上发布了相关代码和模型&#xff0c;提供了使用Python编写的API。如果您要使用ChatGPT&#xff0c;您可以通过以下步骤进行下载和安装&#xff1a; 在GitHub上下载&#xff1a;您…

【vue】 vue2 中使用 Tinymce 富文本编辑器

文章目录Tinymce 效果一、安装依赖二、封装组件-Tinymce.vue三、汉化文件-zh_CN.js四、vue使用组件封装五、整体目录结构六、可能会遇到的问题import "tinymce/icons/default" 路径找不到需要升级tinymce版本Tinymce 效果 一、安装依赖 npm i tinymce5.1.0 -S npm i…

计算机组成原理实验一(完整)

在VC中使用调试功能将下列语句运行的内存存放结果截图&#xff0c;每运行一句需截图一次。 #include<stdio.h> int main() {int a 你的学号末两位-100; //0x&#xff1f;&#xff1f;&#xff1f;&#xff1f;&#xff1f;&#xff1f;&#xff1f;&#xff1f;&#x…

【Redis 进阶之路】3. Redis 主从 以及哨兵

Redis 主从 以及哨兵 单实例Redis 不足&#xff1a; 上述的是一个单实例的Redis。 我们可以先分析下有哪些不足&#xff1a; 单点故障 &#xff08;是每个单实例必须面对的问题&#xff09;容量有限 &#xff08;Redis毕竟是缓存型数据库&#xff0c;容量取决于服务器分配的容…

多目标优化算法评价指标(performance metrics)

参考Performance metrics in multi-objective optimization​​​​​​​ Riquelme, N., Lcken, C. V., & Baran, B. (2015, 19-23 Oct. 2015). Performance metrics in multi-objective optimization. Paper presented at the 2015 Latin American Computing Conference…

SpringBoot整合ES 实现简单项目(七)

一直在烂尾&#xff0c;对&#xff0c;说的就是你&#xff0c;楼. 上一章简单介绍了 SpringBoot 整合 ES (六), 如果没有看过,请观看上一章 这一章节老蝴蝶做一个简单的 ES 查询项目 一. pom.xml 添加依赖 <!--引入MySql的驱动--><dependency><groupId>mys…

小林coding——图解MySQL

文章目录基础篇执行一条select语句&#xff0c;期间发生了什么&#xff1f;MySQL一行记录是怎么存储的&#xff1f;索引篇索引常见面试题什么是索引&#xff1f;索引的分类&#xff1f;小结从数据页的角度看B树为什么MySQL采用B树作为索引&#xff1f;MySQL单表不要超过2000W行…

ElasticSearch分片与Lucene Index

在ES中一个索引有一个或者多个分片构成&#xff0c;在创建索引的时候可以设置主分片和副本分片的数量&#xff0c;当主分片确定之后就不可以再修改了(因为路由需要基于这个数量来分发请求)&#xff0c;而副本分片数量随时可以修改 PUT /myIndex {"settings" : {&quo…

使用ensp软件模拟DNS服务器实验

DNS服务器介绍&#xff1a; DNS服务器&#xff08;Domain Name Server&#xff0c;域名服务器&#xff09;是进行域名和与之相对应的IP地址进行转换的服务器。它起到将人类易于记忆的域名映射到相应的机器可识别的IP地址的作用。 DNS服务器中保存了一张域名和与之相对应的IP地…

Flutter 中 Provider 基本使用

前言&#xff1a; Provider.of<XXX>(context).数据 Provider.of<XXX>(context).方法 ChangeNotifier&#xff1a;这个是真正数据&#xff08;状态&#xff09;存放的地方。我们自己创建的provider 是混入ChangeNotifier 的。 一 安装 在pub.dev 上搜索provider …

2.技巧※(0x3f:从周赛中学算法 2022下)

来自0x3f【从周赛中学算法 - 2022 年周赛题目总结&#xff08;下篇&#xff09;】&#xff1a;https://leetcode.cn/circle/discuss/WR1MJP/ 技巧指一些比较套路的算法&#xff0c;包括双指针、滑动窗口、二分&#xff08;主要指二分答案&#xff09;、前缀和、差分、前后缀分解…

TypeScript由浅到深(下篇)

目录 七、TypeScript泛型编程 泛型实现类型参数化: 泛型接口和泛型类的使用: 泛型约束: 映射类型: TypeScript条件类型&#xff08;Conditional Types&#xff09;: 在条件类型中推断&#xff08;inter&#xff09;: 分发条件类型&#xff08;Distributive Conditional …

【Java基础】day15

day15 一、为什么需要使用多线程&#xff1f; 1、资源利用率提升&#xff0c;程序处理效率提高 2、软件运行效率提升 3、使用线程可以把占据时间长的程序中的任务放到后台去处理 4、充分利用 CPU 资源&#xff0c;多核 CPU 的情况下会更高效 二、Spring Boot 的启动流程&…

搭建个人网站没有公网IP地址可以吗?

搭建网站不一定需要公网IP地址&#xff0c;甚至都不需要云服务器或虚拟主机。可以先在本地个人电脑中搭建一个网站&#xff1b;然后网站需要为公网上的其他访客提供访问&#xff1b;所以&#xff0c;需要内网穿透&#xff0c;映射公网域名进行访问。但是完全没必要&#xff0c;…

一文了解Gralde

&#x1f3e0;个人主页&#xff1a;shark-Gao &#x1f9d1;个人简介&#xff1a;大家好&#xff0c;我是shark-Gao&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f389;目前状况&#xff1a;23届毕业生&#xff0c;目前在某公司实习&#x1f…

python黑马程序员(单例模式工厂模式)笔记

一、单例模式 1、设计模式就是一种编程套路 使用特定的套路得到特定的效果 2、什么时单例设计模式 单例模式就是对一个类&#xff0c;只获取其唯一的类实例对象&#xff0c;持续复用它 节省内存 节省创建对象的开销 非单例模式效果&#xff1a; # 演示单例模式的效果 # 非…

chatgpt相关关键字

听了一堂chatgpt的课程&#xff0c;真假参半&#xff0c;但积累了一些关键词。不知道这些关键字会在什么时候起到作用&#xff0c;先记录下来作为灵感积累 1 自然进化的过程&#xff0c;是人选择工具&#xff0c;也是工具选择人 2 Copliot-自动编程&#xff0c;感觉适用于独立新…

安卓 Windows 通过ts链接获取m3u8视频地址进行视频下载

目录 环境&#xff1a; 解决思路及过程&#xff1a; .TS——> .m3u8 1.利用安卓视频缓存机制合成视频 1.1 找到鲨鱼浏览器目录 1.2 进入Android/data/com.zhijianzhuoyue.sharkbrowser/cashe 缓存目录 1.3 显示隐藏文件 1.4 进入可以看到两个随机生成的视频文件夹&…