【Linux学习】进程间通信 (1) —— 管道

下面是有关进程通信中管道的相关介绍,希望对你有所帮助!

小海编程心语录-CSDN博客

1. 进程通信的基本概念

1.1 概念

进程间通信简称 IPC ,指两个进程之间的通信。 IPC的方式通常有管道(包括无名管道和命名管道)、消息队列、信号量、共享存储、Socket、Streams等。其中 Socket和Streams支持不同主机上的两个进程IPC。

1.2 目的

  1. 数据传输:一个进程需要将它的数据发送给另一个进程。
  2. 资源共享:多个进程之间共享同样的资源。
  3. 通知事件:一个进程需要向另一个或一组进程发送消息,通知它们发生了某种事件。
  4. 进程控制:有些进程希望完全控制另一个进程的执行(如Debug进程),该控制进程希望能够拦截另一个进程的所有操作,并能够及时知道它的状态改变。

1.3 通信方式 

  1. UNIX IPC: 管道、FIFO、信号
  2. System V IPC: 信号量、消息队列、共享内存
  3. Socket IPC: 基于Socket进程间通信

2. 管道 

把一个进程连接到另一个进程的数据流称为管道,是一个半双工的通信方式。

管道分为有名管道无名管道两种,它们的区别是:

无名管道只能在有亲缘关系的进程之间进行通信。

有名管道又称为命名管道,可以在任意两个进程之间进行通信。

2.1 无名管道 

//函数原型
#include <unistd.h>

int pipe( int fd[2] );

匿名管道适用于一对一的、具有亲缘关系的进程间的通信

是一个半双工的通信方式,具有固定的读端和写端。

管道可以看做是一种特殊的文件,对管道的读写可以使用普通的read() ,write()函数,但管道不属于任何文件系统的,只存在于内存中。

2.1.1 如何操作无名管道

  1. 创建 :(pipe函数用来创建无名管道)
  2. 操作 :(read读;write写)  写是 fd[1],读是 fd[0]
  3. 关闭操作端口 :(close)

2.1.2 示例代码 

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

int main()
{
    //创建无名管道
    int fd[2];
    pipe(fd);
    
    if(fork() == 0)
    {
        close(fd[0]);   //读关闭
        char *buf = "hello world"; 
        write(fd[1], buf, strlen(buf)); //写操作
    }
    else
    {
        close(fd[1]);  //写关闭
        char showbuf[100];
        bzero(showbuf, 100);  //清空缓冲区

        read(fd[0], showbuf, 100); //读操作

        printf("txt is :%s\n", showbuf); //打印内容

        exit(0);
      
    }
}

代码运行结果

2.2 有名管道 

//函数原型
#include <sys/types.h>
#include <sys/stat.h>

int mkfifo(const char *pathname, mode_t mode);
//  pathname:具名管道的名称 
//  mode:文件权限模式,例如0666

具名管道通常又被称为FIFO,它是对无名管道的一种改进,其更接近普通文件,有文件名、可以open打开、支持read()/write()等读写操作

Linux在共享文件夹下,创建管道文件是创建不了的,运行结果为空,因此要将执行文件移到非共享文件夹下。因为共享文件夹和Windows是共享的,有些文件windows是没有的。

特性

它可以使互不相关的两个进程实现彼此通信

该管道可以通过路径名来指出,并且在文件系统中是可见的。在建立管道之后,两个进程就可以把它当作普通文件进行读写,使用非常方便。

FIFO严格遵循先进先出原则,对管道及FIFO的读总是从开始处返回数据,对它们的写则把数据添加到末尾。有名管道不支持如Iseek()等文件的定位操作

2.2.1 如何操作具名管道

  1. 创建有名管道文件 :(mkfifo即是命令也是函数;mknod也可以创建管道文件)
  2. 打开有名管道 :(open)
  3. 读/写 :(read/write)
  4. 关闭 :(close)

具名管道一旦没有任何读者和写者,系统判定管道处于空闲状态,会释放管道中的所有数据

1.写者

  1. 创建有名管道文件 mkfifo()
  2. 打开有名管道 open()
  3. 创建缓冲区,写内容 buf
  4. 写操作 write()
  5. 关闭有名管道 close()

2.读者

  1. 打开有名管道 open()
  2. 创建缓冲区,清空缓冲区 buf bzero()
  3. 读操作,打印 read()
  4. 关闭有名管道 close()

2.2.2 示例代码 

//读者
#include <stdio.h> 
#include <unistd.h> 
#include <sys/stat.h> 
#include <string.h> 
#include <sys/types.h> 
#include <fcntl.h> 
#include <stdlib.h> 

int main()
{
    int fd = open("./fifo", O_RDWR);  //打开有名管道

    char showbuf[100];   //创建缓冲区
    bzero(showbuf, 100);  //清空缓冲区

    read(fd, showbuf, 100);  //读

    printf("%s\n", showbuf); //打印

    close(fd);  //关闭

    return 0;

}
//写者
#include <stdio.h> 
#include <unistd.h> 
#include <sys/stat.h> 
#include <string.h> 
#include <sys/types.h> 
#include <fcntl.h> 
#include <stdlib.h> 

int main()
{
    mkfifo("./fifo", 0666);    //创建有名管道文件

    int fd = open("./fifo", O_RDWR);  //打开有名管道

    char *buf = "hello world";   //写
    write(fd, buf, strlen(buf));

    close(fd);   //关闭

    return 0;

}

注意:

在Linux在共享文件夹下,创建管道文件是创建不了的,运行结果为空,因此要将执行文件移到非共享文件夹下,这里我把执行文件放到家目录的test文件夹下了。

打开两个终端执行命令,这里可用Ctrl+shift+n快速打开相同路径下的终端

代码运行结果

3. 相关练习

编写两个程序,一个客户端、一个服务器端,服务器端创建并且监视管道,发现如果有数据就把它保存到指定位置,客户端将当前系统时间和自己的PID写入管道 

3.1 客户端

//cilent 客户端
#include <stdio.h> 
#include <unistd.h> 
#include <sys/stat.h> 
#include <string.h> 
#include <sys/types.h> 
#include <fcntl.h> 
#include <stdlib.h> 
#include <time.h>
int main()
{
    int fd = open("./fifo", O_RDWR);  //打开有名管道

    char buf[1000];     //创建缓冲区
    time_t tim;

    while(1)
    {
        bzero(buf,1000);      //清空缓冲区
        time(&tim);         //时间
        sprintf(buf,"[%d]:  %s",getpid(),ctime(&tim)); //打印到buf指向的字符串中

        write(fd,buf,strlen(buf)); //写操作,在日志文件中写入数据
        
        sleep(2);

    }
    
    return 0;

}

3.2 服务器端 

//server 服务器端
#include <stdio.h> 
#include <unistd.h> 
#include <sys/stat.h> 
#include <string.h> 
#include <sys/types.h> 
#include <fcntl.h> 
#include <stdlib.h> 

int main()
{
    mkfifo("./fifo", 0666);    //创建有名管道文件
    int logfd = open("./log.txt",O_RDWR | O_CREAT,0777); //创建日志文件
    int fd = open("./fifo", O_RDWR);  //打开有名管道

    char buf[1000];     //创建缓冲区
    while(1)
    {
        bzero(buf,1000);      //清空缓冲区
        read(fd,buf,1000);     //读取缓冲区数据
        write(logfd,buf,strlen(buf)); //在日志文件中写入数据
    }
    
    return 0;

}

代码运行结果 


如果喜欢请不吝给予三连支持!

小海编程心语录-CSDN博客

 

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

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

相关文章

复现Apache HTTPD 多后缀解析漏洞

准备一个纯净的Ubuntu系统 1.先更新一下安装列表 sudo apt-get update 2.安装dockers.io sudo apt install docker.io 查看是否安装成功 docker -v 3. 查看是否安装pip,没有的话就安装 sudo apt-get install python3-pip 4. 安装docker-compose pip install docker-comp…

性能测试工具

性能测试工具 1.Jmeter 环境搭建1.安装JDK2.安装Jmeter1.下载2.安装3.环境配置 3.Jmeter 文件目录介绍1.bin目录2.docs 目录3.printable_docs目录4.lib目录 4.修改默认配置1.汉化配置2.修改主题 5.元件的基本介绍6.元件的作用域作用域的原则 7.元件的执行顺序 1.Jmeter 环境搭建…

Axure RP 9 for Mac/win:重新定义交互原型设计的未来

在当今数字化时代&#xff0c;交互原型设计已成为产品开发中不可或缺的一环。Axure RP 9作为一款功能强大的交互原型设计软件&#xff0c;凭借其出色的性能和用户友好的界面&#xff0c;赢得了广大设计师的青睐。 Axure RP 9不仅支持Mac和Windows两大主流操作系统&#xff0c;…

C#数据类型变量、常量

一个变量只不过是一个供程序操作的存储区的名字。 在 C# 中&#xff0c;变量是用于存储和表示数据的标识符&#xff0c;在声明变量时&#xff0c;您需要指定变量的类型&#xff0c;并且可以选择性地为其分配一个初始值。 在 C# 中&#xff0c;每个变量都有一个特定的类型&…

三能一体运营体系助力政企支撑水平提升

生产力的发展是现代社会孜孜不倦的追求&#xff0c;由此产生了我们熟悉的“机械化、电子化、信息化”乃至现今正在发生的“智能化”四次工业革命。这些是由技术的突破性发展带来的&#xff0c;但我们也注意到生产力发展的另一个助力&#xff0c;即生产效率的提升&#xff0c;19…

指数分布的理解,推导与应用

指数分布的定义 在浙大版的教材中&#xff0c;指数分布的定义如下&#xff1a; 若连续型的随机变量 X X X的概率密度为&#xff1a; f ( x ) { 1 θ e − x θ , x>0 0 , 其他 f(x) \begin{cases} \frac{1}{\theta} e^{-\frac{x}{\theta}}, & \text{x>0}\\ 0, &a…

编程基础:掌握运算符与优先级

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、运算符的基石&#xff1a;加减乘除 二、比较运算符&#xff1a;判断数值大小 三、整除…

Tensorflow入门实战 P01-实现手写数字识别mnist

目录 1、背景&#xff1a;MNIST手写数字识别 2、完整代码&#xff08;Tensorflow&#xff09;&#xff1a; 3、运行过程及结果&#xff1a; 4、小结&#xff08;还是很清晰的&#xff09; 5、 展望 &#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客…

智慧水务可视化大屏,一屏纵览水务信息。

智慧水务可视化大屏通常需要展现以下几类信息&#xff1a; 01.实时监测数据&#xff1a; 包括水源水质、水压、水位、水流速等实时监测数据&#xff0c;通过图表、曲线等形式展示&#xff0c;帮助监测人员了解当前水务系统的运行状态。 02.设备运行状态&#xff1a; 展示水泵…

监控上网的软件有哪些?含泪推荐的电脑监控软件

监控上网的软件有很多&#xff0c;企业选择的时候应该遵循什么样的原则呢&#xff1f;鄙人愚见&#xff0c;认为以下四项原则是选择监控软件时首要考虑的。 1、功能需求&#xff1a; 监控软件不应该只是起到控制上网的作用&#xff0c;因为一些泄密行为可能是通过USB接口、打印…

AI大模型的口语练习APP

开发一个使用第三方大模型的口语练习APP涉及多个步骤&#xff0c;从需求分析到部署上线。以下是详细的开发流程和关键步骤&#xff0c;通过系统化的流程和合适的技术选型&#xff0c;可以有效地开发出一个功能丰富、用户体验良好的口语练习APP。北京木奇移动技术有限公司&#…

Ipad air6买什么电容笔?5款超值精品平替电容笔推荐!

电容笔作为ipad的最佳拍档&#xff0c;为学生党和打工人带来了极大的便利&#xff0c;二者搭配效率真的大大提升&#xff0c;但是&#xff0c;如何选购一支适合自己的电容笔呢&#xff1f;作为一个对数码设备非常感兴趣并且有一定了解的人&#xff0c;我根据自己多年的使用经验…

DeepDriving | CUDA编程-03:线程层级

本文来源公众号“DeepDriving”&#xff0c;仅用于学术分享&#xff0c;侵权删&#xff0c;干货满满。 原文链接&#xff1a;CUDA编程-03:线程层级 DeepDriving | CUDA编程-01&#xff1a; 搭建CUDA编程环境-CSDN博客 DeepDriving | CUDA编程-02&#xff1a; 初识CUDA编程-C…

【搜索】BFS

#include <iostream> #include <cstring> #include <queue>using namespace std;const int N 110;typedef pair<int, int> PII;int n, m; int g[N][N], d[N][N];//存放地图//存每一个点到起点的距离int bfs() {queue< PII > q;q.push({0, 0});m…

变量命名的艺术:让你的代码更具可读性

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、引言&#xff1a;为何变量命名如此重要&#xff1f; 二、变量命名的基本规则 1. 避免数…

Threejs路径规划_基于A*算法案例完整版

上节利用了A*实现了基础的路径规划&#xff0c;这节把整个功能完善好&#xff0c;A*算法一方面是基于当前点找到可以到达的点&#xff0c;计算从出发点到此点&#xff0c;以及此点到目的地的总成本&#xff0c;比较出最小的那个&#xff0c;再用最小成本的点继续找到它可以到达…

无线领夹麦克风哪个品牌音质最好,揭秘无线领夹麦哪个牌子好用

​随着社交媒体和内容创作的兴起&#xff0c;清晰可靠的音频捕捉已成为打造高品质作品的关键要素。无线领夹麦克风因其轻巧设计和用户友好的接口而受到青睐&#xff0c;它能够确保你的声音在任何环境下都能被完美捕捉。经过精心测试和对比&#xff0c;以下几款无线领夹麦克风是…

用手机打印需要下载什么软件

在快节奏的现代生活中&#xff0c;打印需求无处不在&#xff0c;无论是工作文件、学习资料还是生活小贴士&#xff0c;都可能需要一纸呈现。然而&#xff0c;传统的打印方式往往受限于时间和地点&#xff0c;让人倍感不便。今天&#xff0c;就为大家推荐一款便捷又省钱的手机打…

解锁合同管理的新路径:低代码与定制开发的完美结合

引言 合同管理在企业中扮演着至关重要的角色。无论是与供应商、客户还是合作伙伴之间的合作&#xff0c;合同都是约束双方责任和权利的关键文档。然而&#xff0c;随着业务的不断增长和全球化的发展&#xff0c;合同管理变得越来越复杂。传统的合同管理方法往往面临着诸多挑战&…

影响程序员发展,首个关于“软件供应链安全”国家标准发布,你该知道的10个问题!【附标准全文】

近日&#xff0c;GB/T 43698-2024《网络安全技术 软件供应链安全要求》作为国内首个软件供应链安全的国标&#xff0c;对于程序员的影响深远。该标准的实施&#xff0c;不仅为程序员提供了明确的软件安全开发指导&#xff0c;还强化了他们在软件开发过程中对安全性的重视。程序…