【hello Linux】进程间通信——命名管道

目录

 1. 命令行的命名管道

 2. 命名管道

 1. 命名管道的创建

 2. 命名管道的使用


Linux🌷 

在上篇中我们说到,可以使用匿名管道完成父子进程间的通信,它是让子进程继承父进程,从而达到让两个进程看到同一份资源;

如果我们想让两个互不相关的进程间进行通信,我们应该使用命名管道,也就是这篇博客所讲的内容!它是利用 路径+文件名 确定唯一的文件,从而使两个独立的进程看到同一份资源;

先来看一下在命令行中两进程的相互通信:

 1. 命令行的命名管道

1. 我们可以使用 mkfifo 文件名 创建命名管道文件;

 经过查看此文件标识以p开头,是一个管道文件;

2. 利用管道文件进行进程间通信;

 2. 命名管道

 1. 命名管道的创建

#include <sys/types.h>
#include <sys/stat.h>

int mkfifo(const char* pathname,mode_t mode);

pathname:管道文件的路径+管道文件名;

mode:管道文件的权限;

返回值:管道文件创建成功返回0,创建失败返回-1,并设置错误码;

上述内容如果忘记的话,在Linux中,可以使用 man 3 mkfifo 查询mkfifo函数的具体使用方法;

创建示例: 

上述中,我们在当前目录下创建了一个管道文件,并将它的权限设置为666,经过查看我们发现创建的fifo管道文件权限是664,其实这是因为受了权限掩码umask的影响;

为避免受权限掩码的影响,我们在创建管道文件前,可以使用umask(0),将权限掩码至0;

注意:这次设置只是设置当前程序的权限掩码,不影响整个系统;

 2. 命名管道的使用

1. 使用命名管道进行进程间数据的传送;

结果演示:

 在输入的时候,输错的话可以使用 ctrl backspace 删除后重新输入;

源代码:

comm.h:将所有用到的头文件放入此文件中

 server.c:在此文件中完成了命名管道文件的创建,并从管道文件中取数据的功能;

 client.c:在此文件中完成了将从键盘输入的数据传入管道文件中;

makefile:书写依赖关系与依赖方法 ;

2. 使用命名管道进行简单进程间的控制;

效果演示:

  只需要修改 server.c 的内容即可:

#include "comm.h"
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

int main()
{
  //创建命名管道
  umask(0);
  if(mkfifo(MY_FIFO,0666)<0)    
  {    
    perror("mkfifo");    
    return 1;    
  }    
  //打开命名管道    
  int fd = open(MY_FIFO,O_RDONLY);    
  if(fd<0)    
  {    
    perror("open fail");    
    return 1;    
  }    
  //业务逻辑    
  while(1)    
  {    
    char buffer[64]={0};    
    ssize_t s = read(fd,buffer,sizeof(buffer));    
    if(s>0)    
    {    
      buffer[s-1]=0;    
      if(strcmp(buffer,"show")==0)    
      {    
        if(fork()==0)    
        {    
          execl("/usr/bin/ls","ls","-l",NULL);    
          return 1;    
        }    
        waitpid(-1,NULL,0);    
      }    
      else if(strcmp(buffer,"sl")==0)    
      {    
        if(fork()==0)    
        {                                                                                     
          execl("/usr/bin/sl","sl",NULL);    
          return 1;    
        }     
        waitpid(-1,NULL,0);    
      }                                        
      else 
      {
        printf("client say # %s\n",buffer);
      }
    }
    else if(s==0)
    {
      printf("client quit...\n");
      break;
    }
    else 
    {
      perror("read");
      break;
    }
  }
  //关闭管道文件
  close(fd);
  return 0;
}

其实质上先从管道文件中读取数据,然后将读取到的数据,与自己设置的条件进行比对,符合条件的,创建子进程——>程序替换,使子进程去完成另一个程序,从而达到此效果!🔮

在这里要提的一点是:

利用管道文件通信,是将数据放入内核缓冲区中的,不会刷新到管道文件中;

如下可以验证:

 我们将server先睡眠50秒,也就是说在50秒之内server不会读取管道文件中的数据;

 从client端输入数据到管道文件中,利用shell脚本对管道文件进行观察;

发现管道文件大小一直是0;

坚持打卡!😀

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

瞳绣

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值