进程间通信学习笔记(有名管道和无名管道)

news2025/2/27 21:14:10

进程间通信方式:

  • 无名管道(pipe)
  • 有名管道(fifo)
  • 信号(signal)
  • 共享内存(mmap)
  • 套接字(socket)

 无名管道:

        在内核里面开辟一片内存,进程1和进程2都可以通过这片内存进行通信

无名管道特点:
  • 只能用于具有亲缘关系的进程之间的通信(比如父子进程、兄弟进程)
  • 单工的通信模式,具有固定的读端和写端(只能一个进程写、一个进程读,不能反过来)
  • 无名管道创建时会返回两个文件描述符,分别用于读写管道(一个进程只能用一个描述符,因为是单工通信)
无名管道创建-pipe
#include <unistd.h>
int pipe(int pfd[2]);
  • 成功时返回0,失败时返回EOF
  • pfd包含两个元素的整形数组,用来保存文件描述符
  • pfd[0]用于读管道;pfd[1]用于写管道

示例代码:

#include <stdio.h>
#include <unistd.h>
#include <string.h>
int main()
{
    int pfd[2];
    int re;
    char buf[20] = {0};
    __pid_t pid;
    re = pipe(pfd);
    if(re < 0)
    {
        perror("pipe");
        return 0;
    }
    printf("%d,%d\n",pfd[0],pfd[1]);
    pid = fork();
    if(pid < 0)
    {
        perror("fork");
        return 0;
    }else if(pid == 0)//子进程
    {
        close(pfd[0]);
        while (1)
        {
            strcpy(buf,"hahahahhahah");
            write(pfd[1],buf,strlen(buf));
            sleep(1);
        }
    }else // 父进程
    {
        close(pfd[1]);
        while (1)
        {
            re = read(pfd[0],buf,20);
            if(re > 0)
            {
                printf("red pipe=%s\n",buf);
            }
        } 
    }
}

 运行结果:

创建两个子线程,两个子线程对管道就行写,一个父进程对管道进行读,示例代码:

#include <stdio.h>
#include <unistd.h>
#include <string.h>
int main()
{
    int pfd[2];
    int re,i;
    char buf[40] = {0};
    __pid_t pid;
    re = pipe(pfd);
    if(re < 0)
    {
        perror("pipe");
        return 0;
    }
    printf("%d,%d\n",pfd[0],pfd[1]);
    for(i = 0;i < 2;i++)
    {
        pid = fork();
        if(pid < 0)
        {
            perror("fork");
            return 0;
        }
        else if(pid > 0)// 父进程
        {
            
        }
        else //子进程
        {
            break; 
        }
    }
    if (i == 2)//父进程执行到这里
    {
        close(pfd[1]);
        while (1)
        {
            memset(buf,0,40);
            re = read(pfd[0],buf,20);
            if(re > 0)
            {
                printf("%s\n",buf);
            }
        }
        return 0;
    }
    if (i == 1)
    {
        close(pfd[0]);
        while (1)
        {
            strcpy(buf,"this is 2 process");
            write(pfd[1],buf,strlen(buf));
            usleep(930000);
        }
        return 0;
    }
    if (i == 0)
    {
        close(pfd[0]);
        while (1)
        {
            strcpy(buf,"this is 1 process");
            write(pfd[1],buf,strlen(buf));
            sleep(1);
        }
        return 0;
    }
}

 运行结果:

无名管道读写特性:

1.读管道:

(1)管道中有数据,read返回实际读到的字节数

(2)管道中无数据:

  • 管道写端被全部关闭(就是读写全关闭),read返回0(好像读到文件结尾)
  • 写端没有全部被关闭(就是把读关闭,没有关闭写),read阻塞等待(不就的将来可能有数据抵达,此时让出cpu)

2.写管道:

(1)管道读端全部被关闭(就是读写全关闭),进程异常终止(也可以使用SIGPIPE信号,使进程不终止)

(2)管道读端没有全部关闭(就是把写关闭,没有关闭读):

  • 管道已满,write阻塞(管道是64k)
  • 管道未满,write将数据写入,并返回实际写入的字节数

有名管道(fifo)特点:

  • 有名管道可以使非亲缘的两个进程互相通信
  • 通过路径名称来操作,在文件系统中可见,但内容存放在内存中(不是磁盘文件)
  • 文件IO来操作有名管道
  • 遵循先进先出规则
  • 不支持leek操作
  • 单工读写
有名管道创建-mkfifo:
#include <unistd.h>
#include <fcntl.h>
int mkfifo(const char *path,mode_t mode);
  • 成功时返回0,失败时返回EOF
  • path创建的管道文件路径
  • mode管道文件的权限,如666

示例代码:

向文件写:

#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
int main()
{
    int re;
    int fd;
    char buf[32];
    re = mkfifo("./myfifo",0666);
    if (re < 0)
    {
        perror("mkfifo");
        // return 0;
    }
    fd = open("./myfifo",O_WRONLY);
    if (fd < 0)
    {
        perror("open");
        return 0;
    }
    while (1)
    {
        fgets(buf,32,stdin);
        write(fd,buf,strlen(buf));
    }
}

 向文件读:

#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <stdlib.h>
int main()
{
    int re;
    int fd;
    char buf[32];
    fd = open("./myfifo",O_RDONLY);
    if (fd < 0)
    {
        perror("open");
        // return 0;
    }
    while (1)
    {
        re = read(fd,buf,32);
        if (re > 0)
        {
            printf("read fifo=%s\n",buf);
        }
        else
        {
            exit(0);
        }
    }
}

运行结果:

open函数四种状态

open(const char *path,O_RDONLY);

open(const char *path,O_RDONLY|O_NONBLOCK);

open(const char *path,O_WRONLY);

open(const char *path,O_WRONLY|O_NONBLOCK); 

 注意事项
  1. 就是程序不能以O_RDWR(读写)模式打开FIFO文件进行读写操作,而其行为也未明确定义,因为如一个管道以读/写方式打开,进程可以读回自己的输出,同时我们通常使用FIFO只是为了单向的传递数据
  2. 第二个参数中的选项O_NONBLOCK,选项O_NONBLOCK表示非阻塞,加上这个选项后,表示open调用是非阻塞的,如果没有这个选项,则表示open调用是阻塞的
  3. 对于以只读方式(O_RDONLY)打开的FIFO文件,如果open调用是阻塞的(即第二个参数为O_RDONLY),除非有一个进程以写方式打开同一个FIFO,否则它不会返回;如果open调用是非阻塞的(即第二个参数为O_RDONLY|O_NONBLOCK),则即使没有其他进程以写方式打开同一个FIFO文件,open调用将成功并立即返回。但如果没有其他进程以只读方式打开同一个FIFO文件,open调用将返回-1,并且FIFO也不会被打开
  4. 数据完整性,如果有多个进程写同一个管道,使用O_WRONLY方式打开管道,如果写入的数据长度小于等于PIPE_BUF(4K),那么或者写入全部字节,或者一个字节都不写入,系统就可以确保数据绝不会交错在一起。

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

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

相关文章

5Why分析法不会用?别担心,精益企业管理咨询公司助你解锁新技能

近年来&#xff0c;为了保持竞争力&#xff0c;许多企业开始转向精益管理&#xff0c;而5Why分析法则是实现这一目标的关键工具之一。然而&#xff0c;对于许多初学者来说&#xff0c;5Why分析法可能显得陌生和复杂。今天&#xff0c;天行健精益企业管理咨询公司就来分享如何运…

浅谈 FD 、PCB 以及 进程内存布局

文章目录 名词解释概念介绍进程内存布局 名词解释 FD&#xff1a;file description&#xff0c;文件描述符&#xff0c;是一个指针变量。 PCB&#xff1a;进程控制块。 概念介绍 我们知道&#xff0c;linux 里面的文件都有基本信息&#xff0c;例如&#xff1a;文件路径、文…

Redis 管道详解

Redis 管道 关键词&#xff1a;Pipeline Pipeline 简介 Redis 是一种基于 C/S 模型以及请求/响应协议的 TCP 服务。通常情况下&#xff0c;一个 Redis 命令的请求、响应遵循以下步骤&#xff1a; 客户端向服务端发送一个查询请求&#xff0c;并监听 Socket 返回&#xff08…

SAR ADC学习笔记(2)

SAR ADC工作原理 基本算法&#xff1a;二进制搜索 / 折半查找 SAR ADC基本结构&#xff1a;采样保持电路、电容DAC、比较器、SAR逻辑

Docker Volume

"Ice in my vein" Docker Volume(存储卷) 什么是存储卷? 存储卷就是: “将宿主机的本地文件系统中存在的某个目录&#xff0c;与容器内部的文件系统上的某一目录建立绑定关系”。 存储卷与容器本身的联合文件系统&#xff1f; 在宿主机上的这个与容器形成绑定关系…

BLEU: a Method for Automatic Evaluation of Machine Translation

文章目录 BLEU: a Method for Automatic Evaluation of Machine Translation背景和意义技术原理考虑 n n n - gram中 n 1 n1 n1 的情况考虑 n n n - gram中 n > 1 n\gt 1 n>1 的情况考虑在文本中的评估初步实验评估和结论统一不同 n n n 值下的评估数值考虑句子长度…

在培训机构中备考PMP为什么题库这么重要?

参加过培训和考试&#xff0c;对题库的了解也就越来越深了&#xff0c;刚开始接触PMP的时候以为学习的时候会像其他考试一样有官方题库进行参考&#xff0c;但是了解后才发现一切都没有我想的那么简单&#xff0c;也是在威班PMP培训的时候才知道题库是多重要。 PMI有官方题库吗…

等保测评与商用密码共铸工控安全“双评合规”新篇章

最近听说了一个段子&#xff1a;“网络安全就像美女的内衣&#xff0c;等保和密评就是最贴身的内衣两件套&#xff0c;上下身一件都不能少。否则你的魔鬼身材&#xff08;核心数据&#xff09;就有可能被色狼&#xff08;黑客&#xff09;一览无余&#xff08;数据泄漏&#xf…

数据安全治理实践路线(中)

数据安全建设阶段主要对数据安全规划进行落地实施&#xff0c;建成与组织相适应的数据安全治理能力&#xff0c;包括组织架构的建设、制度体系的完善、技术工具的建立和人员能力的培养等。通过数据安全规划&#xff0c;组织对如何从零开始建设数据安全治理体系有了一定认知&…

数据分析-Pandas数据如何图示规律

数据分析-Pandas数据如何图示规律 数据分析和处理中&#xff0c;难免会遇到各种数据&#xff0c;那么数据呈现怎样的规律呢&#xff1f;不管金融数据&#xff0c;风控数据&#xff0c;营销数据等等&#xff0c;莫不如此。如何通过图示展示数据的规律&#xff1f; 数据表&…

大语言模型推理加速技术:模型压缩篇

原文&#xff1a;大语言模型推理加速技术&#xff1a;模型压缩篇 - 知乎 目录 简介 量化(Quantization) LLM.int8() GPTQ SmoothQuant AWQ 精简Attention 共享Attention参数 Multi-Query Attention Grouped-Query Attention 稀疏Attention Sliding Window Attenti…

【QT+QGIS跨平台编译】之五十二:【QGIS_CORE跨平台编译】—【qgsexpressionlexer.cpp生成】

文章目录 一、Flex二、生成来源三、构建过程一、Flex Flex (fast lexical analyser generator) 是 Lex 的另一个替代品。它经常和自由软件 Bison 语法分析器生成器 一起使用。Flex 最初由 Vern Paxson 于 1987 年用 C 语言写成。 “flex 是一个生成扫描器的工具,能够识别文本中…

QYYB-01 无线雨量报警仪 集监测 采集 记录 报警一体机

产品概述 无线雨量报警仪&#xff0c;又名简易雨量报警器、遥测雨量报警仪&#xff0c;是一款可以实时测量并显示降雨量的仪器&#xff0c;支持无线传输数据、同步显示新数据、数据超标自动报警、自动存储数据、查询和导出数据等多项功能&#xff0c;由翻斗式雨量传感器、数据采…

什么是高可用架构

一、什么是高可用 在运维中&#xff0c;经常听到高可用&#xff0c;那么什么是高可用架构呢&#xff1f;通俗点讲&#xff0c;高可用就是在服务故障&#xff0c;节点宕机的情况下&#xff0c;业务能够保证不中断&#xff0c;服务正常运行。 举个例子&#xff0c;支付宝&#…

ruoyi-nbcio从spring2.7.18升级springboot到3.1.7,java从java8升级到17(二)

更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码&#xff1a; https://gitee.com/nbacheng/ruoyi-nbcio 演示地址&#xff1a; http://122.227.135.243:9666 更多nbcio-boot功能请看演示系统 gitee源代码地址 后端代码&#xff1a; https://gitee.com/nbach…

抽象的后端

Connection refused: no further information 出现这条代码的核心是你使用redis&#xff0c;但是本地没有开启redis服务 如何启动redis服务 第一步&#xff1a;确定你安装了对应的框架 以spring为例 <dependency><groupId>org.springframework.boot</group…

Android Jni的介绍和简单Demo实现

Android Jni的介绍和简单Demo实现 文章目录 Android Jni的介绍和简单Demo实现一、JNI的简单介绍JNINDKJni的开发背景&#xff1a;**JNI在 Android 开发里的主要应用场景&#xff1a;** 二、JNI的简单Demo1、Demo主要界面和效果展示2、CMake编译加载文件add_library 指令的加载库…

Unity Shader - sahder变体剔除

文章目录 吐槽优化方案 - 目前最靠谱的方式shadercsharp 吐槽 我之所以单独写这边文章&#xff0c;是因为之前写的一篇&#xff1a; Unity Shader - Built-in管线下优化变体&#xff0c;编辑后&#xff0c;无法保存&#xff0c;一直提示&#xff1a;操作超时。 等了差不多 3…

开发框架DevExpress XAF - Entity Framework Core 8支持.NET 8性能基准

DevExpress XAF是一款强大的现代应用程序框架&#xff0c;允许同时开发ASP.NET和WinForms。XAF采用模块化设计&#xff0c;开发人员可以选择内建模块&#xff0c;也可以自行创建&#xff0c;从而以更快的速度和比开发人员当前更强有力的方式创建应用程序。 对于使用Entity Fra…

详解顺序结构滑动窗口处理算法

&#x1f380;个人主页&#xff1a; https://zhangxiaoshu.blog.csdn.net &#x1f4e2;欢迎大家&#xff1a;关注&#x1f50d;点赞&#x1f44d;评论&#x1f4dd;收藏⭐️&#xff0c;如有错误敬请指正! &#x1f495;未来很长&#xff0c;值得我们全力奔赴更美好的生活&…