Linux之进程间通信——管道

article/2025/9/23 0:47:18

文章目录

  • 前言
  • 一、进程间通信
    • 1.概念
    • 2.目的
    • 3.进程间通信分类
  • 二、管道
    • 1.管道介绍
    • 2.管道分类
      • 1.匿名管道
        • pipi
        • 创建管道文件,打开读写端
        • fork子进程
        • 关闭父进程的写入端,关闭子进程的读取端
        • 读写特征
        • 管道特征
      • 2.命名管道
        • mkfifo
        • 创建管道文件
        • 删除管道文件
        • 通信
  • 三、匿名管道和命名管道的区别和联系
  • 总结


前言

管道是Linux中最古老的进程间通信的方式,本文介绍了进程间通信的相关概念,主要介绍了匿名管道和命名管道。


一、进程间通信

1.概念

什么是进程间通信?

进程具有独立性,每个进程之间是互不干扰的状态,但是一个大的项目,不会只让一个进程独立完成所有工作,所以进程间是一定会有通信的情况,同时进程间通信的成本一定不低(通信的本质:OS需要直接或间接给通信双方的进程提供“内存空间”,而要通信的进程,必须看到一份公共的资源)。
成本不低的原因:我们需要让不同的进程看到同一份资源。

2.目的

进程间通信的目的是:

  • 数据传输:一个进程需要将它的数据发送给另一个进程;
  • 资源共享:多个进程之间共享同一个资源;
  • 通知事件:一个进程需要向另一个或一组进程发送消息,通知它(它们)发生了某件事(例如:子进程终止时,要通知父进程);
  • 进程控制:有的进程希望完全控制另一个进程大的执行(例如:Debug进程)。

为什么需要进程间通信?
有时候我们需要多进程协同,共同完成某种业务内容。例如:管道。

3.进程间通信分类

我们所说的不同通信种类本质上是按照:上面所说的资源是OS中的哪一个模块提供的来划分的。如:文件系统提供的叫做管道通信;OS对应的System V模块提供的……

  1. 采用标准的做法:System V进程间通信(聚焦在本地通信,如共享内存)、POSIX进程间通信(让通信过程可以跨主机);
  2. 采用文件的做法:管道——基于文件系统(匿名管道、命名管道)。

本文主要介绍的是管道。

二、管道

1.管道介绍

  1. 管道是Unix中最古老的进程间通信的方式,我们把连接两个进程的数据流称为“管道”。
  2. 任何一个文件包括两套资源:1.file的操作方法;2.属于自己的内核缓冲区。所以父子进程有一份公共的资源:文件系统提供的内核缓冲区,父进程可以向对应的文件的文件缓冲区写入,子进程可以在对应的文件缓冲区读取,这样就可以完成进程间通信。这种方式中被子进程写入和父进程读取的文件,我们称为管道文件。管道文件本质就是内存级文件(不需要IO)。
  3. 两个进程如何看到同一个管道文件?
    fork创建子进程,管道创建时,要分别以读和写的方式打开同一个文件(如果父进程是以只读或只写的方式(其中一种方式)打开文件,子进程也只会继承只读或者只写,父子双方打开文件的方式一样,导致无法完成单向通信)
    父子进程正确进行管道通信的方式:
  4. 父进程创建管道,同时具有读写权限。
    在这里插入图片描述
  5. 父进程创建子进程,子进程继承管道以及对管道的读写
    在这里插入图片描述
  6. 父进程关闭读取端,子进程关闭写入端。自此父进程只能向管道中写入,子进程只能从管道中读取,完成了父子进程的单向通讯。
    在这里插入图片描述

2.管道分类

管道根据是否具有文件名,分为匿名管道和有名管道。

1.匿名管道

通过父进程创建子进程,子进程继承文件地址的方式,让父子进程看到同一个内存级文件,该内存级文件没有名称,则就称为匿名管道。匿名管道可以用来进行父进程和子进程之间的进程间通信。

pipi

pipi创建一个管道,只需要调用pipe系统调用。
它的头文件是unistd.h;调用成功就返回0,调用失败就返回-1;其参数是输出型参数。
在这里插入图片描述

创建管道文件,打开读写端

  1 #include<stdio.h>2 #include<unistd.h>3 #include<assert.h>4 int main()5 {6         int fds[2];7         int n = pipe(fds);8         assert(n == 0);9         printf("fds[0]:%d\n",fds[0]);10         printf("fds[1]:%d\n",fds[1]);11         return 0;12 }

在这里插入图片描述
因此,fds[0]:3代表读取,fds[1]:4代表写入;

fork子进程

  1 #include<stdio.h>2 #include<unistd.h>3 #include<assert.h>4 int main()5 {6         int fds[2];7         int n = pipe(fds);8         assert(n == 0);9         pid_t id = fork();10         assert(id >= 0);11         if(id == 0)//子进程12         {13                 //子进程通信14                 exit(0);15         } 16         //父进程17         n = waitpid(id, NULL, 0);18         assert(n == id);19         return 0;20 }

关闭父进程的写入端,关闭子进程的读取端

  1 #include<stdio.h>2 #include<unistd.h>3 #include<assert.h>4 #include<sys/types.h>5 #include<sys/stat.h>6 #include<fcntl.h>7 #include<sys/wait.h>8 #include<string.h>9 #include<stdlib.h>10 int main()11 {12         int fds[2];13         int n = pipe(fds);14         assert(n == 0);15         pid_t id = fork();16         assert(id >= 0);17         if(id == 0)//子进程18         {19                 //子进程通信,关闭子进程的读取端,即子进程进行写入20                 close(fds[0]);21                 const char* s = "你好,我是子进程,正在进行通信";22                 int cnt = 0;23                 while(1)24                 {25                         cnt++;26                         char buffer[1024];27                         snprintf(buffer, sizeof buffer, "child -> parent say:%s [%d], [%d]",s,cnt,getpid());28                         write(fds[1], buffer, strlen(buffer));29                         sleep(1);//每一秒写一次30                 }31                 close(fds[1]);//退出子进程前关闭文件写入端32                 exit(0);33         }34         //父进程35         close(fds[1]);//父进程关闭写入端,即父进程进行读取36         while(1)37         {38                 char buffer[1024];39                 ssize_t s = read(fds[0], buffer, sizeof(buffer) - 1);40                 if(s > 0) buffer[s] = 0;41                 printf("Get Message : %s | mypid = %d\n", buffer, getpid());42         }43         n = waitpid(id, NULL, 0);44         assert(n == id);45         close(fds[0]);//退出程序前,关闭读取端46         return 0;47 }

在这里插入图片描述

读写特征

  1. 读快,写慢
    子进程休眠时,不再写入,父进程仍在读取(如果管道内没有数据,而读端在读取,则会默认直接阻塞当前正在读取的进程);
  1 #include<stdio.h>2 #include<unistd.h>3 #include<assert.h>4 #include<sys/types.h>5 #include<sys/stat.h>6 #include<fcntl.h>7 #include<sys/wait.h>8 #include<string.h>9 #include<stdlib.h>10 int main()11 {12         int fds[2];13         int n = pipe(fds);14         assert(n == 0);15         pid_t id = fork();16         assert(id >= 0);17         if(id == 0)//子进程18         {19                 //子进程通信,关闭子进程的读取端,即子进程进行写入20                 close(fds[0]);21                 const char* s = "你好,我是子进程,正在进行通信";22                 int cnt = 0;23                 while(1)24                 {25                         cnt++;26                         char buffer[1024];27                         snprintf(buffer, sizeof buffer, "child -> parent say:%s [%d], [%d]",s,cnt,getpid());28                         write(fds[1], buffer, strlen(buffer));29                         sleep(50);//每一秒写一次30                 }31                 close(fds[1]);//退出子进程前关闭文件写入端32                 exit(0);33         }34         //父进程35         close(fds[1]);//父进程关闭写入端,即父进程进行读取36         while(1)37         {38                 char buffer[1024];39                 printf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");40                 ssize_t s = read(fds[0], buffer, sizeof(buffer) - 1);41                 printf("888888888888888888888888888888888888!!\n");42                 if(s > 0) buffer[s] = 0;43                 printf("Get Message : %s | mypid = %d\n", buffer, getpid());44         }45         n = waitpid(id, NULL, 0);46         assert(n == id);47         close(fds[0]);//退出程序前,关闭读取端48         return 0;49 }

在这里插入图片描述

2.读慢写快
读取管道的进程一直不进行读取,而写端一直在写入。写端可以向管道内写入,但是管道是固定大小的缓冲区,不断的只写不读管道会被写满。满了以后就不能再写入了,此时写端会处于阻塞状态。
文件test.c

  1 #include<stdio.h>2 #include<unistd.h>3 #include<assert.h>4 #include<sys/types.h>5 #include<sys/stat.h>6 #include<fcntl.h>7 #include<sys/wait.h>8 #include<string.h>9 #include<stdlib.h>10 int main()11 {12         int fds[2];13         int n = pipe(fds);14         assert(n == 0);15         pid_t id = fork();16         assert(id >= 0);17         if(id == 0)//子进程18         {19                 //子进程通信,关闭子进程的读取端,即子进程进行写入20                 close(fds[0]);21                 const char* s = "你好,我是子进程,正在进行通信";22                 int cnt = 0;23                 while(1)24                 {25                         cnt++;26                         char buffer[1024];27                         snprintf(buffer, sizeof buffer, "child -> parent say:%s [%d], [%d]",s,cnt,getpid());28                         write(fds[1], buffer, strlen(buffer));29                         printf("count: %d\n",cnt);30                 }31                 close(fds[1]);//退出子进程前关闭文件写入端32                 exit(0);33         }34         //父进程35         close(fds[1]);//父进程关闭写入端,即父进程进行读取36         while(1)37         {38                 sleep(50);//父进程不读39                 char buffer[1024];40                 ssize_t s = read(fds[0], buffer, sizeof(buffer) - 1);41                 if(s > 0) buffer[s] = 0;42                 printf("Get Message : %s | mypid = %d\n", buffer, getpid());43         }44         n = waitpid(id, NULL, 0);45         assert(n == id);46         close(fds[0]);//退出程序前,关闭读取端47         return 0;48 }

在这里插入图片描述
如果,让父进程只sleep(2)的话,读取的速度稍微比较慢:
在这里插入图片描述
这种情况,写端是将数据塞到管道内,管道读取是安装指定大小读取(并非一行一行的读取,最初安装一行来读取是因为写入的慢,一次只写一行数据,数据就被读取了)。

  1. 写入端关闭,则读取到0(管道末尾)读取端关闭
    文件test.c
  1 #include<stdio.h>2 #include<unistd.h>3 #include<assert.h>4 #include<sys/types.h>5 #include<sys/stat.h>6 #include<fcntl.h>7 #include<sys/wait.h>8 #include<string.h>9 #include<stdlib.h>10 int main()11 {12         int fds[2];13         int n = pipe(fds);14         assert(n == 0);15         pid_t id = fork();16         assert(id >= 0);17         if(id == 0)//子进程18         {19                 //子进程通信,关闭子进程的读取端,即子进程进行写入20                 close(fds[0]);21                 const char* s = "你好,我是子进程,正在进行通信";22                 int cnt = 0;23                 while(1)24                 {25                         cnt++;26                         char buffer[1024];27                         snprintf(buffer, sizeof buffer, "child -> parent say:%s [%d], [%d]",s,cnt,getpid());28                         write(fds[1], buffer, strlen(buffer));29                         printf("count: %d\n",cnt);30                         break;31                 }32                 close(fds[1]);//退出子进程前关闭文件写入端33                 exit(0);34         }35         //父进程36         close(fds[1]);//父进程关闭写入端,即父进程进行读取37         while(1)38         {39                 sleep(2);//父进程不读40                 char buffer[1024];41                 ssize_t s = read(fds[0], buffer, sizeof(buffer) - 1);42                 if(s > 0)43                 {44                         buffer[s] = 0;45                         printf("Get Message : %s | mypid = %d\n", buffer, getpid());46                 }47                 else if(s == 0)//写入端关闭,读到文件末尾了48                 {49                         printf("read: %d\n", s);50                         break;//关闭读取端      51                 }52         }53         n = waitpid(id, NULL, 0);54         assert(n == id);55         close(fds[0]);//退出程序前,关闭读取端56         return 0;57 }

在这里插入图片描述
4. 读取端关闭,写入端直接关闭
关闭读取端后,写入端就没有意义了,因此OS会给写入的进程发送信号,终止该进程。

  1 #include<stdio.h>2 #include<unistd.h>3 #include<assert.h>4 #include<sys/types.h>5 #include<sys/stat.h>6 #include<fcntl.h>7 #include<sys/wait.h>8 #include<string.h>9 #include<stdlib.h>10 int main()11 {12         int fds[2];13         int n = pipe(fds);14         assert(n == 0);15         pid_t id = fork();16         assert(id >= 0);17         if(id == 0)//子进程18         {19                 //子进程通信,关闭子进程的读取端,即子进程进行写入20                 close(fds[0]);21                 const char* s = "你好,我是子进程,正在进行通信";22                 int cnt = 0;23                 while(1)24                 {25                         cnt++;26                         char buffer[1024];27                         snprintf(buffer, sizeof buffer, "child -> parent say:%s [%d], [%d]",s,cnt,getpid());28                         write(fds[1], buffer, strlen(buffer));29                         printf("count: %d\n",cnt);30                 }       31                 close(fds[1]);//退出子进程前关闭文件写入端32                 printf("子进程关闭写入端\n");33                 exit(0);34         }35         //父进程36         close(fds[1]);//父进程关闭写入端,即父进程进行读取37         while(1)38         {39                 sleep(2);//父进程不读40                 char buffer[1024];41                 ssize_t s = read(fds[0], buffer, sizeof(buffer) - 1);42                 if(s > 0)43                 {44                         buffer[s] = 0;45                         printf("Get Message : %s | mypid = %d\n", buffer, getpid());46                 }47                         break;//关闭读取端      48         }49         close(fds[0]);//退出程序前,关闭读取端50         printf("父进程关闭读取端\n");51         n = waitpid(id, NULL, 0);52         assert(n == id);53         return 0;54 }

在这里插入图片描述

管道特征

  1. 管道的生命周期是根据进程的,进程退出,则管道释放;
  2. 管道可以用来进行具有血缘关系的进程间通信(常用于父子进程);
  3. 管道是面向字节流的;
  4. 半双工——单向管道(特殊);
  5. 互斥与同步机制——对共享资源进行保护的方案。

2.命名管道

匿名管道的限制就是只能在具有血缘关系的进程间通信,那么如果是两个毫不相干的进程间通信交互呢?
如果我们想要在两个不相关的进程之间进行通信,我们可以使用FIFO文件,它被称为命名管道。(命名管道是一种特殊类型的文件)

mkfifo

在这里插入图片描述
在当前路径下创建命名管道:

mkfifo named_pipe

在这里插入图片描述

创建管道文件

comm.hpp文件(同一份资源)

  1 #pragma once2 #include<iostream>3 #include<sys/types.h>4 #include<sys/stat.h>5 #include<fcntl.h>6 #include<cassert>7 #include<cstring>8 #include<cerrno>9 using namespace std;10 #define NAMED_PIPO "/tmp/mypipe.name"11 #include<string>12 bool createFIFO(const string &path)13 {14         umask(0);15         int n = mkfifo(path.c_str(), 0666);16         if(n ==0) return true;17         else18         {19                 cout<<"errno:"<<errno<<"err string:"<<strerror(errno)<<endl;20         }21         return false;22 }

server.cc文件(读取端)

  1 #include"comm.hpp"2 int main()3 {4         bool ret = createFIFO(NAMED_PIPO);5         assert(ret == true);6         (void)ret;7         return 0;8 }

在这里插入图片描述

删除管道文件

unlink
在这里插入图片描述
头文件:unistd.h;参数为const char* path;返回值:如果删除成功返回0,如果删除失败返回-1
使用:
在这里插入图片描述
在comm.hpp中封装删除函数

 23 void removeFIFO(const string &path)24 {25         int n = unlink(path.c_str());26         assert(n == 0);27         (void)n;//避免因为没有使用n导致爆警告28 }

在文件server中调用删除函数

  1 #include"comm.hpp"2 int main()3 {4         bool ret = createFIFO(NAMED_PIPO);5         assert(ret == true);6         (void)ret;      7         8         removeFIFO(NAMED_PIPO);9         return 0;10 }

到此管道文件的创建和删除就完成了,接下来我们进入通信阶段:

通信

clinet.cc文件(写入端)

  1 #include"comm.hpp"2 int main()3 {4         printf("HHHHHH\n");5         int wfd = open(NAMED_PIPO, O_WRONLY);6         if(wfd < 0) exit(1);7         char buffer[1024];8         while(1)9         {10                 cout<<"Please say:";11                 fgets(buffer, sizeof buffer, stdin);//if(strlen(buffer) > 0) buffer[strlen(buffer) - 1] = 0;12                 ssize_t s = write(wfd, buffer, strlen(buffer));13                 assert(s == strlen(buffer));14                 (void)s;15         }16         close(wfd);17         return 0;18 }

server.cc文件(读取端)

  1 #include"comm.hpp"2 int main()3 {4         bool ret = createFIFO(NAMED_PIPO);5         assert(ret);6         (void)ret;7         int rfd = open(NAMED_PIPO, O_RDONLY);8         if(rfd < 0) exit(1);9 10         char buffer[1024];11         while(1)12         {13                 ssize_t s = read(rfd, buffer, sizeof(buffer) - 1);14                 if(s > 0)15                 {16                         buffer[s] = 0;17                         cout<<"client -> server"<< buffer<<endl;18                 }19                 else if(s == 0)20                 {21                         cout<<"client quit. me, too"<<endl;22                         break;23                 }24                 else25                 {26                         cout<<"err string:"<<strerror(errno)<<endl;27                         break;28                 }29         }30         removeFIFO(NAMED_PIPO);31         return 0;32 }

comm.hpp文件(同一份资源)

  1 #pragma once2 #include<iostream>3 #include<sys/types.h>4 #include<sys/stat.h>5 #include<fcntl.h>6 #include<cassert>7 #include<cstring>8 #include<cerrno>9 #include<unistd.h>10 #include<stdlib.h>11 #include<stdio.h>12 using namespace std;13 #define NAMED_PIPO "/tmp/mypipe.name"14 #include<string>15 bool createFIFO(const string &path)16 {17         umask(0);18         int n = mkfifo(path.c_str(), 0666);19         if(n ==0) return true;20         else21         {22                 cout<<"errno:"<<errno<<"err string:"<<strerror(errno)<<endl;23         }24         return false;25 }26 void removeFIFO(const string &path)27 {28         int n = unlink(path.c_str());29         assert(n == 0);30         (void)n;//避免因为没有使用n导致爆警告31 }

运行:
在这里插入图片描述
我们发现读端每次会多打印一行空白,实际上是将写入端最后的Enter也作为数据传送了,因此我们将写端缓冲区的最后一个位置内容改为0即可。

if(strlen(buffer) > 0) buffer[strlen(buffer) - 1] = 0;

在这里插入图片描述

三、匿名管道和命名管道的区别和联系

它们都是往管道文件里写东西,

两个进程打开同一个文件:站在内核的角度,第二个文件不需要继续创建struct file对象,因为OS会识别到需要打开的文件已经被打开了。在内核中,两个进程此时就看到了同一份资源,有对应文件的操作方法和缓冲区,不需要将数据刷新到磁盘上(不需要IO),所以无论是匿名管道还是命名管道,本质都是内存级文件。

匿名管道是通过继承的方式让两个进程看到一个文件(资源),命名管道是通过让不同的进程打开指定名称(路径+文件名)的文件,来看待同一份资源。所以命名管道是通过文件的文件名来唯一标定资源的唯一性,而匿名管道是通过继承的方式来标定的。


总结

以上就是今天要讲的内容,本文介绍了进程间通信——管道的相关概念。
本文作者目前也是正在学习Linux相关的知识,如果文章中的内有错误或者不严谨的部分,欢迎大家在评论区指出,也欢迎大家在评论区提问、交流。
最后,如果本篇文章对你有所启发的话,希望可以多多支持作者,谢谢大家!


http://chatgpt.dhexx.cn/article/YKfoUcrg.shtml

相关文章

Linux系统中的管道通信

目录 管道如何通信 管道的访问控制机制&#xff1a; 匿名管道 匿名管道数据传输的原理 如何使用&#xff08;代码案例&#xff09; 用C/C代码编译实现父子进程间通信案例 &#xff1a; 思路 实现 命名管道 为什么要有命名管道 回归进程间通信的本质 匿名管道的短板…

linux 管道 (单管道与双管道)

管道的局限性&#xff1a; ①数据不能进程自己写&#xff0c;自己读。 ②管道中数据不可反复读取。-旦读走, 管道中不再存在。 ③采用半双工通信方式&#xff0c;数据只能在单方向上流动。 ④只能在有公共祖先的进程间使用管道 单通道将小写字母改为大写例程&#xff1a; #in…

Linux 管道文件

管道分为无名管道和有名管道两种管道&#xff0c;管道文件是建立在内存之上可以同时被两个进程访问的文件。 先来说说有名管道&#xff1a; mkfifo函数创建有名管道&#xff0c;属于系统调用。 在linux操作系统中为实现下述功能&#xff0c; 先创建一个有名管道文件fifo。 …

【Linux】Linux 管道命令Cut、sort、wc、uniq、tee、tr【一】

目录 &#x1f40b;Cut— 根据条件 从命令结果中 提取 对应内容 &#x1f40b;sort—可针对文本文件的内容&#xff0c;以行为单位来排序。 &#x1f40b;wc命令— 显示/统计 指定文件 字节数, 单词数, 行数 信息. &#x1f40b; uniq— 用于检查及删除文本文件中重复出现的…

Linux管道命令(pipe)全

目录 选取命令&#xff1a;cut、grep 传送门 排序命令&#xff1a;sort、wc、uniq 传送门 双向重定向&#xff1a;tee 字符转换命令&#xff1a;tr、col、join、paste、expand 传送门 划分命令&#xff1a;split 传送门 参数代换&#xff1a;xargs 传送门 关于减号…

Linux中管道命令的用法

原文地址&#xff1a;http://blog.csdn.net/wirelessqa/article/details/8968381 一. 管道命令 管道命令操作符是&#xff1a;”|”,它只能处理经由前面一个指令传出的正确输出信息&#xff0c;对错误信息信息没有直接处理能力。然后&#xff0c;传递给下一个命令&#xff0c;…

Linux管道符

管道 1、管道符 管道符&#xff1a;| 作用&#xff1a;管道是一种通信机制&#xff0c;通常用于进程间的通信。它表现出来的形式将前面每一个进程的输出&#xff08;stdout&#xff09;直接作为下一个进程的输入&#xff08;stdin&#xff09;。 2、过滤功能 # ls / | gr…

linux管道相关命令

目标 cutsortwcuniqteetrsplitawksedgrep 准备数据 zhangsan 68 99 26 lisi 98 66 96 wangwu 38 33 86 zhaoliu 78 44 36 maq 88 22 66 zhouba 98 44 46以上是成绩表信息 使用 逗号 分割, 第一列 是 姓名, 第二列是 语文成绩, 第三列是 数学成绩, 第四列是 英语成绩 需求1: …

Linux管道到底能有多快?

【CSDN 编者按】本文作者通过一个示例程序&#xff0c;演示了通过Linux管道读写数据的性能优化过程&#xff0c;使吞吐量从最初的 3.5GiB/s&#xff0c;提高到最终的 65GiB/s。即便只是一个小例子&#xff0c;可它涉及的知识点却不少&#xff0c;包括零拷贝操作、环形缓冲区、分…

linux管道pipe详解

管道 管道的概念&#xff1a; 管道是一种最基本的IPC机制&#xff0c;作用于有血缘关系的进程之间&#xff0c;完成数据传递。调用pipe系统函数即可创建一个管道。有如下特质&#xff1a; 1. 其本质是一个伪文件(实为内核缓冲区) 2. 由两个文件描述符引用&#xff0c;一个表…

Linux管道符|命令使用详解

1. 作用 “|”是Linux管道命令操作符&#xff0c;简称管道符。使用此管道符“|”可以将两个命令分隔开&#xff0c;“|”左边命令的输出就会作为“|”右边命令的输入&#xff0c;此命令可连续使用&#xff0c;第一个命令的输出会作为第二个命令的输入&#xff0c;第二个命令的…

Linux 管道操作符详解

管道操作符 : | 我们在Linux下经常要用到管道操作符&#xff0c;也就是"|"&#xff0c;即一个竖线。 这个操作符的作用对于经常使用Linux的人来说&#xff0c;看上去十分直观&#xff1a; 不就是将前一个指令的结果交给后一个指令吗&#xff1f; 举个例子&#xff…

linux之管道符详解

linux之管道符 ’ | ’ 操作详解 管道符主要用于多重命令处理&#xff0c;前面命令的打印结果作为后面命令的输入。简单点说就是&#xff0c;就像工厂的流水线一样&#xff0c;进行完一道工序后&#xff0c;继续传送给下一道工序处理… 举个栗子&#xff1a;对hello.sh文件进行…

【Linux】Linux的管道

管道是Linux由Unix那里继承过来的进程间的通信机制&#xff0c;它是Unix早期的一个重要通信机制。其思想是&#xff0c;在内存中创建一个共享文件&#xff0c;从而使通信双方利用这个共享文件来传递信息。由于这种方式具有单向传递数据的特点&#xff0c;所以这个作为传递消息的…

【Linux】管道

前言 我和前桌上课传纸条&#xff0c;这是一种通信方式。 而我们为什么能过在上课的时候通信? 因为我们通过在纸条上写字进行了数据的传递。 本质上而言&#xff0c;我们两个都能看见一份公共的资源并对其进行读写&#xff0c;那就是小纸条&#xff01; 进程间通信的本质&a…

【嵌入式总复习】Linux管道详解——管道通信、无名管道、有名管道、具体应用示例

目录 管道1. 管道通信1.1 通信模式1.2 管道通信中特殊的名词 2. 无名管道&#xff08;PIPE&#xff09;2.1 无名管道的通信原理2.2 无名管道特点2.3 如何操作无名管道示例1示例2 3. 有名管道&#xff08;FIFO&#xff09;3.1 有名管道的特点3.2 如何操作有名管道 4. 示例4.1 cu…

linux命令管道工作原理与使用方法

一、管道定义 管道是一种两个进程间进行单向通信的机制。因为管道传递数据的单向性&#xff0c;管道又称为半双工管道。管道的这一特点决定了器使用的局限性。管道是Linux支持的最初Unix IPC形式之一&#xff0c;具有以下特点&#xff1a; *** 数据只能由一个进程流向另一个进程…

Linux管道

目录 1.管道概念 2.管道分类 1.匿名管道 1.基本实现与概念 2.站在文件描述符角度-深度理解管道 3.站在内核角度-管道本质 4.管道读写规则 5.管道属性设置与阻塞验证 6.管道特点(匿名) 2.命名管道 1.创建一个命名管道 2.命名管道的打开规则 3.匿名管道与命名管道的区别…

linux中管道的概念,浅谈Linux管道

通过前面的学习&#xff0c;我们已经知道了怎样从文件重定向输入&#xff0c;以及重定向输出到文件。Shell 还有一种功能&#xff0c;就是可以将两个或者多个命令&#xff08;程序或者进程&#xff09;连接到一起&#xff0c;把一个命令的输出作为下一个命令的输入&#xff0c;…

linux管道举例理解

linux管道举例理解 一、管道的定义&#xff1a;“|”二、查找2.1统计当前目录下有多少个文件2.2查看当前目录下的前n&#xff08;3&#xff09;个文件2.3查看wang.txt文件包含i的字符行2.4查看内存使用情况2.5查询进程 三、更改 https://blog.csdn.net/hanhanwanghaha宝藏女孩 …