匿名管道(pipe)和命名管道(mkfifo)

2023-05-16

匿名管道(pipe)和命名管道(mkfifo)

进程间通信必须通过内核提供的通道。

1、匿名管道

匿名管道通过打开的文件描述符来标识的。——用于具有亲缘关系间进程之间的通信。

img

int pipe(int fds[2]);//返回值0表示成功,-1表示失败

fd[0]:读 fd[1]:写
写数据时要关闭读端
读数据时要关闭写端

2、命名管道

命名管道借助于文件系统实现,文件系统中的路径名是全局的,各进程都可以访问,因此可以用文件系统中的路径名来标识一个IPC通道。——用于具有非亲缘关系间进程之间的通信。

命名管道的打开规则:

如果当前打开操作是为读而打开FIFO时
O_NONBLOCK disable:阻塞直到有相应进程为写而打开该FIFO
O_NONBLOCK enable:立刻返回成功
如果当前打开操作是为写而打开FIFO时
O_NONBLOCK disable:阻塞直到有相应进程为读而打开该FIFO
O_NONBLOCK enable:立刻返回失败,错误码为ENXIO

需要注意的是打开的文件描述符默认是阻塞的.

管道的创建

img

管道文件大小为0,没有亲缘关系的文件也能通过管道名,来取到该管道中的缓存。

//创建管道文件 int mkfifo(const char *name,mode_t mode)

//打开管道文件

int fd=open(name,O_RDONLY);读

int fd=open(name,O_WRONLY);写

3、匿名管道与命名管道的区别:

  • 匿名管道是由pipe函数创建 并打开的

  • 命名管道是由mkfifo函数创建 的 ,打开用open

    命名管道和匿名管道唯一的区别就是在创建的打开,一旦这些工作完成后,它们有相同的意义。

匿名管道实例1:

/*
*  父进程通过命令行的方式输入内容(argv[1])写入管道
*  子进程从管道中读取数据并输出到标准输出
*  
*   note: ./pipe hello world
*        仅能输出hello(argv[1]),word(argv[2])不能输出.
*/

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

int main(int argc, char **argv)
{
   int pipefd[2];
   pid_t pid;
   char recv_buf[1024];
   int len;

   if(argc < 2)
   {
      perror("Usage error:");
      exit(1);
   }


   if(pipe(pipefd) < 0)
   {
       perror("pipe()");
       exit(1);
   }

   pid = fork();
   if(-1 == pid)
   {
       perror("fork()");
       exit(1);
   }

   if(0 == pid)
   {
      close(pipefd[1]);
      while((len = read(pipefd[0],recv_buf,10)) > 0 )
         write(1,recv_buf,len);

      puts("\n");
      close(pipefd[0]);

      exit(0);
   }
   else
   {
       close(pipefd[0]);
       write(pipefd[1],argv[1],strlen(argv[1]));
      
       close(pipefd[1]);
       wait(NULL);
       exit(0);
   }

  exit(0);
}

匿名管道实例2:

/*
*  父进程通过命令行的方式输入文件路径名(argv[1])写入管道
*  子进程从管道中读取数据并输出到标准输出
*
*  eg. ./pipe pipe.c
*      ./pipe ./pipe.c
*      ./pipe ./home/user/IPC/pipe.c
*/


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

int main(int argc, char **argv)
{
   int pipefd[2];
   pid_t pid;
   char recv_buf[1024];
   char send_buf[1024];
   int recv_len;
   size_t send_len;
   FILE *fp = NULL;

   if(argc < 2)
   {
      perror("Usage error:");
      exit(1);
   }


   if(pipe(pipefd) < 0)
   {
       perror("pipe()");
       exit(1);
   }

   pid = fork();
   if(-1 == pid)
   {
       perror("fork()");
       exit(1);
   }

   if(0 == pid)
   {
      close(pipefd[1]);
      while((recv_len = read(pipefd[0],recv_buf,10)) > 0 )
         write(1,recv_buf,recv_len);

      puts("\n");
      close(pipefd[0]);

      exit(0);
   }
   else
   {
       close(pipefd[0]);
       fp = fopen(argv[1],"r");
       if(NULL == fp)
       {
           perror("fopen()");
           exit(1);
       }
       
       while((send_len = fread(send_buf,1,10,fp)) > 0)
            write(pipefd[1],send_buf,send_len);
      
       fclose(fp);

       close(pipefd[1]);
       wait(NULL);
       exit(0);
   }

  exit(0);
}

命名管道实例:

公共头文件public.h:

#ifndef PUBLIC_H__
#define PUBLIC_H__

#define MKFIFO_NAME "tp"   //定义管道文件名

#endif

写端代码(write.c):

#include<sys/types.h>
#include<sys/stat.h>
#include<unistd.h>
#include<fcntl.h>
#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
#include<string.h>
#include<signal.h>

#include "public.h"

#define ERR_EXIT(m) \
    do { \
        perror(m); \
        exit(EXIT_FAILURE); \
    } while(0)

int main(int argc, char *argv[])
{
    mkfifo(MKFIFO_NAME, 0644);
    int infd = open("Makefile", O_RDONLY);
    if (infd == -1)
        ERR_EXIT("open error");

    int outfd;
    outfd = open(MKFIFO_NAME, O_WRONLY);
    if (outfd == -1)
        ERR_EXIT("open error");

    char buf[1024];
    int n;
    while ((n = read(infd, buf, 1024)) > 0)
        write(outfd, buf, n);

    close(infd);
    close(outfd);

    return 0;
}

读端代码(read.c):

#include<sys/types.h>
#include<sys/stat.h>
#include<unistd.h>
#include<fcntl.h>
#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
#include<string.h>
#include<signal.h>

#include "public.h"

#define ERR_EXIT(m) \
    do { \
        perror(m); \
        exit(EXIT_FAILURE); \
    } while(0)

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

    int outfd = open("Makefile2", O_WRONLY | O_CREAT | O_TRUNC, 0644);
    if (outfd == -1)
        ERR_EXIT("open error");

    int infd;
    infd = open(MKFIFO_NAME, O_RDONLY);
    if (infd == -1)
        ERR_EXIT("open error");

    char buf[1024];
    int n;
    while ((n = read(infd, buf, 1024)) > 0)
        write(outfd, buf, n);

    close(infd);
    close(outfd);
    unlink(MKFIFO_NAME); // delete a name and possibly the file it refers to
    return 0;
}

PS:部分内容来源于其他博客,侵权删。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

匿名管道(pipe)和命名管道(mkfifo) 的相关文章

随机推荐

  • 临时抱佛脚真的有用吗?

    对于面试 应该有相应的准备 xff0c 对面试公司的背景要有简单的了解 xff0c 对企业文化要有简单的认识 那么最关键的就属于问答环节 你问我答 对于这方面 xff0c 有人喜欢临时抱佛脚 但后来 xff0c 我深刻的认识到 xff0c
  • C语言| char[ ]的输出 和结束符 ‘\0‘

    输出char arr 逐个字符输入输出 c 整个字符串一次输入输出 s printf 34 61 61 61 61 61 61 start 61 61 61 61 61 61 n n 34 char arr 61 39 1 39 39 2
  • python中的isdigit()函数

    s为字符串 s isalnum 所有字符都是数字或者字母 s isalpha 所有字符都是字母 s isdigit 所有字符都是数字 s islower 所有字符都是小写 s isupper 所有字符都是大写 s istitle 所有单词都
  • 【WiFi模块ASP-ESP8266】理论讲解与串口助手验证(超详解)

    大家好 xff0c 我是小政 xff0c 一名自动化专业的在校学生 最近在学习利用opencv进行环境监测 xff0c 需要将获取到的数据通过通信协议传输给stm32 我选择使用wifi模块进行无线通信 xff0c 接下来我会将我从入门到掌
  • 【平衡小车制作】(二)电机驱动(超详解)

    大家好 xff0c 我是小政 本篇文章我将针对平衡小车中的电机控制进行详细的讲解 xff0c 驱动一个电机最重要的就是给它一个PWM信号 xff0c PWM的概念 如何驱动电机及通过改变PWM占空比进行电机调速我会在本篇文章中进行详解 让每
  • 【平衡小车制作】(五)位置式PID、直立环与速度环概念(超详解)

    大家好 xff0c 我是小政 本篇文章我将针对位置式PID算法 直立环 速度环等概念进行详细的讲解 xff0c 让每位小伙伴能够对这三个概念有更加清晰的理解 一 PID控制算法 PID控制 xff0c 即为对偏差进行比例 积分和微分控制 由
  • 【平衡小车制作】(七)串级PID调参及平衡成果展示(超详解)

    大家好 xff0c 我是小政 本篇文章我将针对PID调参进行详细的讲解 xff0c 让每位小伙伴能够对比例 积分 微分三个参数如何调节有更加清晰的理解 一 调参步骤 确立机械中值直立环 xff08 内环 xff09 Kp极性 Kp大小 Kd
  • 第七章:总线

    7 1总线概述 总线概述 总线是一组能为多个部件分时共享的公共信息传送线路 共享是指总线上可以挂接多个部件 xff0c 各个部件之间相互交换的信息都可以通过这组公共线路传送 xff1b 分时是指同一时刻总线上只能传送一个部件发送的信息 总线
  • Jetson 系统监视程序Jtop及Jetson基本信息查询

    开启后的界面如下 xff1a 安装Jetson的监视程序 xff1a 了解安装的Jetpack版本是多少 xff1f 了解 GPU 的使用率 xff1f 了解Jetson机器工作在什么模式下 xff1f 了解CPU用了几个 xff1f 散热
  • MVC设计模式

    MVC模式 xff08 Model View Controller xff09 是软件工程中的一种软件架构模式 xff0c 把软件系统分为三个基本部分 xff1a 模型 xff08 Model xff09 视图 xff08 View xff
  • Docker常用基础命令

    目录 1 docker version 查看版本信息 2 docker info 查看docker的一些信息 3 docker search 镜像搜索 4 docker pull 拉取镜像到本地 5 docker push 推送本地的镜像到
  • 硬件基础之变频器&逆变器

    变频器 amp 逆变器工作原理 基本概念直流产生方波思路正弦波产生原理正弦波产生之制作脉冲正弦波产生之滤波 amp 平均 基本概念 逆变器 xff1a 直流电 xff08 DC xff09 转变为交流电 xff08 AC xff09 变频器
  • 硬件基础之STM32最小系统

    STM32 复位电路时钟电路SWD下载电路BOOT电路RTC时钟电源电路 复位电路 STM32为低电平复位 xff0c 上电瞬间电流可视为交流 xff0c 电容导通 xff08 充电过程 xff0c NRST为低电平 xff0c 两个机械周
  • 数据结构常用的结构体定义

    一 顺序表结构体定义 xff1a typedef struct int data maxsize int length Sqlist 二 单链表结构体定义 xff1a typedef struct LNode int data struct
  • Linux基础入门(常用指令总结)

    相信大家对Linux都不陌生 xff0c 本篇文章就详细介绍一些常用的Linux命令 目录 前言 一 Linux是什么 xff1f 二 常用命令 1 cd 切换文件夹 2 ls 查看目录内容 3 mkdir 创建文件夹 4 touch 创建
  • 第7章:OFDM 信道估计与均衡(2)

    第7章 xff08 2 xff09 内容如下 xff1a 一 瑞利衰落信道介绍二 OFDM经过多径衰落信道的误码率分析三 总结 本文对应的完整可运行代码下载地址 xff1a 123kevin456 OFDM 一 瑞利衰落信道介绍 第 xff
  • 阿里云ECS服务器ubuntu18.04图形界面安装配置

    先说一下我用的ECS配置 服务器配置 xff1a 2 vCPU 4 GiB 系统镜像 xff1a ubuntu18 04 xff08 64位 xff09 本文的配置方法在 ubuntu 16 04 上一样适用 1 安装图形化界面 网上一大堆
  • java多线程-进程与线程基础-1

    基本概念 进程 是并发执行的程序在执行过程中分配和管理资源的基本单位 xff0c 是一个动态概念 xff0c 竟争计算机系统资源的基本单位 每一个进程都有一个自己的地址空 间 xff0c 即进程空间或 xff08 虚空间 xff09 进程空
  • 自由度的理解

    研究六轴机械臂的运动学前 xff0c 需要知道机械臂的自由度的定义 xff1a 物体上的任意一个参考点相对基座坐标系O可进行独立自由运动的数量 自由度的计算十分简洁 例如一个物体如正方体 xff0c 取其中心点作为参照点 xff0c 若该参
  • 匿名管道(pipe)和命名管道(mkfifo)

    匿名管道 xff08 pipe xff09 和命名管道 xff08 mkfifo xff09 进程间通信必须通过内核提供的通道 1 匿名管道 匿名管道通过打开的文件描述符来标识的 用于具有亲缘关系间进程之间的通信 int pipe xff0