Linux高级编程:IPC之管道

一、无名管道

        1.1 无名管道的概述

        管道(pipe)又称无名管道。 无名管道是一种特殊类型的文件,在应用层体现为两个打开的文件描述符。

任何一个进程在创建的时候,系统都会 给他分配4G的虚拟内存,分为3G的用户空间和1G 的内核空间,内核空间是所有进程公有的,无名管道就是创建在内核空间的,多个进程知道 同一个无名管道的空间,就可以利用他来进行通信。

无名管道虽然是在内核空间创建的,但是会给当前用户进程两个文件描述符,一个负责执行 读操作,一个负责执行写操作

     

管道是最古老的UNIX IPC方式,其特点是:

1、半双工,数据在同一时刻只能在一个方向上流动。

2、数据只能从管道的一端写入,从另一端读出。

3、写入管道中的数据遵循先入先出的规则。

4、管道所传送的数据是无格式的,这要求管道的读出方与写入方必须事先约定好数据的格 式,如多少字节算一个消息等。

5、管道不是普通的文件,不属于某个文件系统,其只存在于内存中。

6、管道在内存中对应一个缓冲区。不同的系统其大小不一定相同。

7、从管道读数据是一次性操作,数据一旦被读走,它就从管道中被抛弃,释放空间以便写 更多的数据。

8、管道没有名字,只能在具有公共祖先的进程之间使用

  1.2 无名管道的创建 ---pipe函数

 #include <unistd.h> 

 int pipe(int pipefd[2]);

 功能:创建一个有名管道,返回两个文件描述符负责对管道进行读写操作

参数:

 pipefd:int型数组的首地址,里面有两个元素

 pipefd[0] 负责对管道执行读操作

pipefd[1] 负责对管道执行写操作

返回值: 成功:0 

失败:‐1

案例:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

int main()
{

    // 使用pipe创建一个无名管道
    int fd_pipe[2];

    if (pipe(fd_pipe) == -1)
    {

        perror("fail to pipe");
        exit(1);
    }

printf("fd_pipe[0]=%d\n",fd_pipe[0]);
printf("fd_pipe[1]=%d\n",fd_pipe[1]);


//描述符就可以操作无名管道,所以通过文件IO中的read和write函数对无名管道进行操作
//通过write函数向无名管道中写入数据
 //fd_pipe[1]负责执行写操作
if(write(fd_pipe[1],"hello world",11) == -1){
    perror("fail to write");
    exit(1);
}
printf("测试一下sizeof(hello) =%ld\n",sizeof("hello"));

//写完之后,再写
//如果管道中有数据,再次写入的数据会放在之前数据的后面,不会把之前的数据替
write(fd_pipe[1],"write agin",sizeof("write agin")); //11,strlen 不会将\0记入长度


char buf[32]="kkk";
ssize_t bytes;

//fd_pipe[0]负责执行读操作
if(bytes = read(fd_pipe[0],buf,20)==-1){
    perror("fail  to read");
    exit(1);
}

printf("buf = [%s]\n", buf);
printf("bytes = %ld\n", bytes);



//读完后再读,如果管道中没有数据了 发生阻塞
read(fd_pipe[0],buf,sizeof(buf));

printf("buf = [%s]\n", buf);
printf("bytes = %ld\n", bytes);

read(fd_pipe[0],buf,sizeof(buf));
printf("buf = [%s]\n", buf);
printf("bytes = %ld\n", bytes);



}

 1.3 无名管道实现进程间通信

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

int main(int argc, char const *argv[])
{

    int fd_set[2];
    int ret;
    ret = pipe(fd_set);
    if (ret == -1)
    {
        perror("fail to create pipe");
        exit(1);
    }

    int pid = fork();

    if (pid > 0)
    { // 父进程代码 :从标准输入IO获取字符串,写入管道
        char buf[128] = "";
        while (1)
        {
            fgets(buf, sizeof(buf), stdin);
            buf[strlen(buf) - 1] = '\0'; // 封尾

            // 写入管道
            if (write(fd_set[1], buf, sizeof(buf)) == -1)
            {
                perror("fail to write");
                exit(1);
            }
        }
    }
    else if (pid == 0)
    {
        // 子进程代码:去管道里读
        char buf[128] = "";
        while (1)
        {
            if (read(fd_set[0], buf, sizeof(buf)) == -1)
            {
                perror("fail to read");
                exit(1);
            }
            printf("buf=[%s]\n", buf);
        }
    }
    else if (pid == -1)
    {
        perror("创建进程失败");
        exit(1);
    }

    return 0;
}

注意:

利用无名管道实现进程间的通信,都是父进程创建无名管道,然后再创建子进程,子进 程继承父进程的无名管道的文件描述符,然后父子进程通过读写无名管道实现通信

        1.4 无名管道的读写规律

               1.4.1 读写端都存在,只读不写

                1.4.2 读写端都存在,只写不读

                1.4.3 只有读端,没有写端

                1.4.3 只有写端,没有读端

        1.5 通过fcntl 函数设置文件阻塞特性

二、文件描述符

三、有名管道

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

wpf devexpress项目中添加GridControl绑定数据

本教程讲解了如何添加GridControl到wpf项目中并且绑定数据 原文地址Lesson 1 - Add a GridControl to a Project and Bind it to Data | WPF Controls | DevExpress Documentation 1、使用 DevExpress Template Gallery创建一个新的空白mvvm应用程序&#xff0c;这个项目包括了…

P6入门:项目初始化9-项目详情之资源 Resource

前言 使用项目详细信息查看和编辑有关所选项目的详细信息&#xff0c;在项目创建完成后&#xff0c;初始化项目是一项非常重要的工作&#xff0c;涉及需要设置的内容包括项目名&#xff0c;ID,责任人&#xff0c;日历&#xff0c;预算&#xff0c;资金&#xff0c;分类码等等&…

DRAM和SRAM

特点 Static Random Access Memory&#xff1a;速度快、存储一位需要元器件更多、功耗较大、集成度低、更贵 Dynamic Random Access Memory&#xff1a;容量大、需刷新、附属电路更复杂、功耗较小、集成度高 存储位元 SRAM DRAM 逻辑结构 SRAM 典型的SRAM芯片有6116&am…

RHCE第四次作业

题目 架设一台NFS服务器&#xff0c;并按照以下要求配置 1、开放/nfs/shared目录&#xff0c;供所有用户查询资料 2、开放/nfs/upload目录&#xff0c;为192.168.100.0/24网段主机可以上传目录&#xff0c; 并将所有用户及所属的组映射为nfs-upload,其UID和GID均为210 3、将…

算法笔记-第七章-队列

算法笔记-第七章-队列 队列的相关知识点c中队列queue用法队列的操作序列求和队列约瑟夫环-队列匹配队列 队列的相关知识点 大佬的讲解 c中队列queue用法 一&#xff1a;queue是一种容器转换器模板&#xff0c;调用#include< queue>即可使用队列类 二&#xff1a;使用q…

TDengine 与煤科院五大系统实现兼容性互认,助力煤矿智能化安全体系搭建

近日&#xff0c;涛思数据与煤炭科学技术研究院&#xff08;以下简称煤科院&#xff09;已完成数个产品兼容互认证工作&#xff0c;经双方共同严格测试&#xff0c;涛思数据旗下物联网、工业大数据平台 TDengine V3.X 与煤炭科学技术研究院旗下煤矿复合灾害监测监控预警系统、煤…

超越任务调度的极致:初探分布式定时任务 XXL-JOB 分片广播

XXL-JOB 是一个分布式任务调度平台&#xff0c;支持分片任务执行。 1. 依赖引入 在项目中引入 XXL-JOB 的相关依赖。通常&#xff0c;你需要在项目的 pom.xml 文件中添加如下依赖&#xff1a; <dependency><groupId>com.xuxueli</groupId><artifactId&…

线圈寿命预测 数据集讲解

来自-郭师兄 1.这个是线圈数据的阻抗、电抗等数据&#xff0c;我想根据这个个数据进行线圈寿命预测也就是RUL预测&#xff0c;请问有什么思路吗。 最简单的思路&#xff1a; 数据通过某种方法进行压缩表征到一维再通过 同时需要标签。 确定一个特征 使用降维方法如同PCA来构…

达梦数据库安装

一、官网参考文档 达梦数据库官网&#xff1a;https://www.dameng.com/ &#xff0c;参考文档如下&#xff1a; 最后的文档地址为&#xff1a;Docker安装 | 达梦技术文档 二、dcoker安装 docker基本按照官网来就行&#xff0c;点击相应的链接下载镜像包。 复制到linux中&#x…

面试官问 Spring AOP 中两种代理模式的区别?很多面试者被问懵了

面试官问 Spring AOP 中两种代理模式的区别?很多初学者栽了跟头&#xff0c;快来一起学习吧&#xff01; 代理模式是一种结构性设计模式。为对象提供一个替身&#xff0c;以控制对这个对象的访问。即通过代理对象访问目标对象&#xff0c;并允许在将请求提交给对象前后进行一…

Perl爬虫程序的框架

Perl爬虫程序的框架&#xff0c;这个框架可以用来爬取任何网页的内容。 perl #!/usr/bin/perl use strict; use warnings; use LWP::UserAgent; use HTML::TreeBuilder; # 创建LWP::UserAgent对象 my $ua LWP::UserAgent->new; # 设置代理信息 $ua->proxy(http, ); …

你真的会使用 MySQL中EXPLAIN吗

EXPLAIN是MySQL数据库中一个强大的工具&#xff0c;用于查询性能分析和优化。通过EXPLAIN&#xff0c;你可以查看MySQL查询的执行计划&#xff0c;了解MySQL是如何执行你的查询语句的。这篇文章将详细介绍EXPLAIN的使用&#xff0c;帮助你更好地理解和优化MySQL查询。 为什么使…

Docker - 容器数据卷

Docker - 容器数据卷 什么是容器数据卷 等同于挂载&#xff0c;将容器内的目录地址指向于宿主机文件系统中 直接使用命令来挂载 -v docker run -it -v 主机目录:容器内目录# 测试 docker run -it -v /root:/home centos /bin/bash [rootiZ2zeg7mctvft5renx1qvbZ ~]# docker …

应急响应练习1

目录 1. 提交攻击者的IP地址 2. 识别攻击者使用的操作系统 3. 找出攻击者资产收集所使用的平台 4. 提交攻击者目录扫描所使用的工具名称 5. 提交攻击者首次攻击成功的时间&#xff0c;格式&#xff1a;DD /MM/YY:HH:MM:SS 6. 找到攻击者写入的恶意后门文件&#xff0c;提…

【done】剑指offer46_new:解密数字

题目&#xff1a;力扣165&#xff0c;https://leetcode.cn/problems/ba-shu-zi-fan-yi-cheng-zi-fu-chuan-lcof/description/ 现有一串神秘的密文 ciphertext&#xff0c;经调查&#xff0c;密文的特点和规则如下&#xff1a; 密文由非负整数组成 数字 0-25 分别对应字母 a-z 请…

[工业自动化-19]:西门子S7-15xxx编程 - 软件编程 - PLC程序块、组织块OB与PLC多线程原理、OB、FC、FB、DB

目录 一、PLC的块的种类 1.1 什么是块 1.2 块的种类 1.3 不同块之间的相互调用关系 1.4 OB、FC、FB和DB 二、PLC程序组织块OB 2.1 什么是程序块OB 2.2 为什么需要程序块OB 2.3 PLC有哪些程序块 2.4 如何使用程序块 - OB块的执行顺序和规则 2.5 PLC用户程序主函数&am…

IntelliJ IDEA 安装 GitHub Copilot插件 (最新)

注意&#xff1a; GitHub Copilot 插件对IDEA最低版本要求是2021.2&#xff0c;建议直接用2023.3&#xff0c;一次到位反正后续要升级的。 各个版本的依赖关系&#xff0c;请参照&#xff1a; ##在线安装&#xff1a; 打开 IntelliJ IDEA扩展商店&#xff0c;输入 "Git…

Js 保留关键字

JavaScript 关键字用于标识要执行的操作&#xff0c;和其他任何编程语言一样&#xff0c;JavaScript 保留了一些关键字为自己所用&#xff1b;这些关键字有些在目前的版本中可能没有使用&#xff0c;但在以后 JavaScript 扩展中会用到。 以下是JS中最重要的保留关键字&#xf…

element 周选择器el-date-picker

2023.11.13今天我学习了在使用element 周选择器的时候&#xff0c;我们会发现默认的时间选择为星期日到下一个星期一&#xff0c;如图&#xff1a; 我们需要改成显示星期一到星期天&#xff0c;只需要加一行代码&#xff1a;picker-options <el-date-pickertype"week&…

【反编译系列】一、反编译 .so 文件(IDA Pro)

文章目录 【反编译系列】一、反编译 .so 文件&#xff08;IDA Pro&#xff09;1. 介绍2. 反编译Reference 【反编译系列】一、反编译 .so 文件&#xff08;IDA Pro&#xff09; 1. 介绍 .so 文件是共享对象文件&#xff08;Shared Object file&#xff09;的一种形式&#xf…