IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> Linux进程间通信 -----------------命名管道 -> 正文阅读

[系统运维]Linux进程间通信 -----------------命名管道

上节我们讲了匿名管道,匿名管道是用于具有亲缘关系的进程进行通信的方式。其特点是子进程继承父进程的属性,继承了文件描述表中的信息---打开的文件。而命名管道通信方式是让磁盘上的一个文件,加载到内存,让通信的进程都能看到同一块资源。具体如下图:

?

接下来我们看一看匿名管道的创建过程,具体如下图:

?

接下来我们就要将本节重点-------命名管道

我们先看一个命令行的命名管道通信的实例:

我们创建一个管道文件 : mkfifo pipc.一个进程向pipc中写,一个从pipc中读

?

?当我们在一个进程向管道(pipc)中写入"hello other",另一个进程会收到消息

接来下我们来了解一下命名管道的原理:

首先进程是具有独立性的,进程通信的成本比较高,要实现进程通信必须需要要解决让不同进程看到同一块资源有以下几种方式

1.管道(匿名管道,命令管道(内存文件))

2.共享内存

3.消息队列

4.信号量

这些资源肯定都是操作系统提供的;pipe是通过子进程继承父进程的资源的特性,达到让不同的进程看到同一份资源,但是只适用于具有亲缘关系的进程。命名管道可以让不同进程看到同一块资源,具体如下图:

一旦我们具有了一个命令管道,此时我们只需要让通信双方按照文件操作即可!

注意:命令管道也是基于字节流的,所以实际上,信息传递的时候,是需要双方定制“协议的”,占时不考虑,我会在网络的时候讲解。今天我们就单纯的字符串通信。

1.首先我们编写server。

sever.c

#include"common.h" //定义头文件,方便不同进程拿到同一个路径+文件名


int main()
{
        umask(0);
        int mkid = mkfifo(PATHMANE,0666);   //PATHMANE 是文件名
        if( mkid < 0 )
        {
                perror("mkfifo()");
                exit(1);
        }


        int fd = open(PATHMANE,O_RDONLY);
        if(fd < 0)
        {
                perror("open()");
                exit(1);
        }
        while(1)
        {
                char buf[64] = {0};
                ssize_t ret = read(fd,buf,sizeof(buf));
                if(ret < 0)
                {
                        printf("read is error\n");
                        exit(1);
                }
                else if(ret > 0)
                {
                        printf("client## %s\n",buf);
                }
                else
                {
                        printf("client is qiut\n");
                        break;
                }
        }

        close(fd);

}

?client.c

#include"common.h"
int main()
{
        int fd = open(PATHMANE,O_WRONLY);
        if(fd < 0)
        {
                perror("open()");
                exit(1);
        }
        while(1)
        {
                printf("请输入#:");
                fflush(stdout);

                char buf[64] = {0};
                ssize_t ret = read(0 ,buf,sizeof(buf) -1);
                if(ret < 0)
                {
                        printf("read is error\n");
                        exit(1);
                }
                else if(ret > 0)
                {
                        buf[ret -1 ] = 0;
                        printf("%s\n",buf);

                        write(fd,buf,strlen(buf));
                }
                else
                {
                        printf("client is qiut\n");
                        break;
                }
        }

        close(fd);

}

common.h

#include<stdio.h>
#include<sys/stat.h>
#include<sys/types.h>
#include <fcntl.h>
#include<unistd.h>
#include<sys/wait.h>
#define PATHMANE  "./pipe"


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

makefile

.PHONY:ALL
ALL: client server
client:client.c
        gcc -o $@ $^
server:server.c
        gcc -o $@ $^
.PHONY:clean
clean:
        rm -rf client  server pipe

运行效果如下:

?当然大家也可以增加一些自己的业务逻辑比如:

#include"common.h"


int main()
{
        umask(0);
        int mkid = mkfifo(PATHMANE,0666);
        if( mkid < 0 )
        {
                perror("mkfifo()");
                exit(1);
        }


        int fd = open(PATHMANE,O_RDONLY);
        if(fd < 0)
        {
                perror("open()");
                exit(1);
        }
        while(1)
        {
                char buf[64] = {0};
                ssize_t ret = read(fd,buf,sizeof(buf));
                if(ret < 0)
                {
                        printf("read is error\n");
                        exit(1);
                }
                else if(ret > 0)
                {
                        if(strcmp(buf,"show") == 0) //client输入“show”,server执行ls- l
                        {
                                if( fork() == 0)
                                {
                                        execl("/usr/bin/ls","ls","-l",NULL);
                                        exit(1);
                                }
                                waitpid(-1,NULL,0);
                        }
                       if(strcmp(buf,"memory") == 0 )//client输入“memory”,server执行free
                        {
                                if(fork () == 0)
                                {
                                        execl("/usr/bin/free","free","-m",NULL);
                                        exit(1);
                                }
                                waitpid(-1,NULL,0);
                        }
                        printf("client## %s\n",buf);
                }
                else
                {
                        printf("client is qiut\n");
                        break;
                }
        }

        close(fd);

}

另外需要注意的是:命名管道是一直会在内存的,不会讲数据刷新到磁盘

我们让server休眠50秒之后在读,我们client一直在写,但是pipe管道文件一直没有变化,可以得出结论,命令管道是不会向磁盘上写入的。?

  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2022-04-22 19:19:35  更:2022-04-22 19:22:10 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 21:00:23-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码