系统编程02-管道PIPE(pipe、mkfifo、access)

本文介绍了Linux下进程间通信的两种管道方式:无名管道和有名管道。详细讲解了它们的工作机制、创建方法及使用示例,包括父子进程间的通信和使用mkfifo创建有名管道。同时,文中提到了管道通信的特点,如半双工、单方向及适用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

一、进程之间通信方式(重点)

1.为什么要实现进程之间的通信

2.在linux下,进程之间通信方式有哪些,都有什么特点

二、进程之间通信方式之一 无名管道

1.什么是无名管道?作用机制如何?

2.创建一个无名管道文件

3.例子1: 初始化的读端写端的文件描述符是多少?

4.例子2:实现使用无名管道,让父子进程通信

三、进程之间通信之一 有名管道。

1.什么是有名管道?机制如何?

2.如何创建有名管道?  -> mkfifo()  -> man 3 mkfifo  (先进先出)

3.例子1:尝试在家目录下创建一个有名管道,名字为fifo1

4、有名管道文件实现两个进程的通信

作业:实现两个进程之间的互聊 


一、进程之间通信方式(重点)

1.为什么要实现进程之间的通信

例如:
./project  -> 开启了一个名字叫project的进程。
./test     -> 开启了一个名字叫test的进程。
 通过学习进程之间的通信,使得不同的进程之间能够实现数据的交换,例如test进程发送数据给project进程,project进程收到数据之后,
根据数据做出相应的事情。 (test进程控制project进程)


2.在linux下,进程之间通信方式有哪些,都有什么特点

以下几种进程之间的通信有一个共通的特点,都是只能在同一台主机内部的进程使用。
1)管道通信。-->pipe
管道通信分为有名管道与无名管道,管道是一个特殊的文件,进程通过将数据写入到管道中,另外一个进程从管道中读取数据出来。
2)信号
在linux下,有非常多的信号,例如:暂停,继续,停止...,某一个进程通过发送信号给另外一个进程,从而控制另外一个进程的运行状态。
3)消息队列 -->message
某一个进程把消息发送到队列上,另外一个进程就可以读取队列上的数据,消息队列好处:进程可以读取队列上某一个特定的数据。
4)共享内存 -->share mem
多个进程访问同一片内存空间。
5)信号量

二、进程之间通信方式之一 无名管道

1.什么是无名管道?作用机制如何?

无名管道只能作用于亲缘关系的进程之间的通信,例如父子进程。无名管道就是一个没有名字的管道文件,相当于一个队列结构,fd[1]为写入端(入队)fd[0]为读出端(出队)。其中信息读出后即删除,再次读取时即为下一个信息。


2.创建一个无名管道文件

#include <unistd.h>
int pipe(int pipefd[2]);   -> 执行这个函数之后,得到两个文件描述符     //  int  *pipefd
函数作用:
    创建一个无名管道文件
参数:
    pipefd   一个具有2个int类型变量的数组。(2个文件描述符)
返回值:
    成功:0
    失败:-1
注意:
>1、pipefd[0] -> 读端   pipefd[1] -> 写端
>2、没有名字,因此无法使用 open( )。
>3、只能用于亲缘进程间(比如父子进程、兄弟进程、祖孙进程……)通信,因为他只能在一个进程中被创建出来,然后通过继承的方式将他的文件描述符传递给子进程
>4、半双工(单方向)工作方式:读写端分开。

3.例子1: 初始化的读端写端的文件描述符是多少?

#include<stdio.h>
#include <unistd.h>

int main(int argc,char *argv[])
{
    int fd[2];
    //创建一个无名管道文件 ,创建成功之后 pipefd[0] 读端  pipefd[1] 写端
    pipe(fd);

    printf("fd[0]:%d fd[1]:%d\n",fd[0],fd[1]); //3  4

    return 0;
}

说明:无名管道文件描述符的值,是从1024个值里面按照顺序拿取

4.例子2:实现使用无名管道,让父子进程通信

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

int main()
{
    int fd[2];
    //创建一个无名管道文件 ,创建成功之后 fd[0] 读端  fd[1] 写端
    pipe(fd); //注意,不可以使用open打开无名管道,因为它没有名字,创建的时候默认已经打开了
    
    //创建一个子进程 ,实现父进程与子进程的通信
    pid_t id = fork();
    if(id == -1)/
<think>好的,我现在需要回答用户关于Linux系统管道功能的问题。首先,我得回忆一下管道的基本概念,确保自己理解正确。管道主要用于将一个命令的输出作为另一个命令的输入,这样可以实现命令之间的协作,不需要中间文件。 接下来,我需要考虑用户可能的背景。用户可能已经了解了一些Linux基础知识,比如设备管理和常用命令,所以不需要从最基础讲起。但为了确保全面性,还是应该覆盖管道的基本功能、符号、工作原理以及使用场景。 然后,我需要组织回答的结构。通常,分点说明会更清晰。可能需要分为功能定义、符号与语法、工作原理、使用场景、优缺点以及示例。这样用户可以逐步理解,并找到他们最关心的部分。 关于功能定义,要明确管道的作用是连接命令,传递数据流。符号方面,用户可能知道竖线符号“|”,但需要强调它的位置在命令之间。工作原理部分需要简单解释管道如何在内核中通过缓冲区传输数据,避免涉及太多复杂细节,比如内存管理或进程调度,以免让用户感到困惑。 使用场景方面,举例说明常见的情况,比如过滤日志、统计文件信息、实时监控等。这些例子可以帮助用户更好地理解如何应用管道。优缺点部分需要客观,指出管道的高效性和局限性,比如单向流动和实时处理的特点。 最后,提供一些示例命令,让用户能够直观看到管道如何工作。例如,结合ls和grep来查找特定文件,或者使用多个管道连接多个命令。这些例子应该简单易懂,避免使用复杂命令,让新手也能跟上。 需要检查是否有遗漏的重要点,比如管道和重定向的区别,或者匿名管道与命名管道的不同。用户可能混淆管道和重定向,所以可以简要提及,但主要焦点还是管道本身。 还要确保语言简洁,避免使用过多技术术语,必要时进行解释。例如,提到“标准输出”和“标准输入”时,可以简单说明这些是程序默认的输入输出通道。 最后,总结部分要强调管道的强大之处,并鼓励用户多实践,以加深理解。同时,提醒用户注意命令的顺序和管道的限制,比如不能处理需要交互输入的命令。</think>--- ### Linux管道Pipe)的功能详解 --- #### **一、核心功能** 管道(**Pipe**)是Linux中**进程间通信(IPC)**的核心机制之一,主要用于将**前一个命令的输出**直接作为**后一个命令的输入**。其核心目的是**串联多个命令**,实现数据流的自动化处理。 --- #### **二、管道符号与语法** - **符号**:`|` - **语法**:`命令1 | 命令2 | 命令3 ...` ```bash # 示例:统计当前目录中.txt文件的数量 ls *.txt | wc -l ``` --- #### **三、工作原理** 1. **单向流动** 数据从左侧命令的**标准输出(stdout)**流向右侧命令的**标准输入(stdin)**。 2. **内存缓冲** 内核通过**缓冲区**临时存储数据,无需生成中间文件,效率极高。 3. **并行执行** 所有命令同时运行,左侧命令一边输出,右侧命令一边处理(类似流水线)。 --- #### **四、典型使用场景** | **场景** | **示例** | |--------------------|--------------------------------------------------------------------------| | **过滤数据** | `cat log.txt | grep "error"`(提取含“error”的行) | | **统计信息** | `ps aux | grep nginx | wc -l`(统计Nginx进程数量) | | **数据转换** | `ls -l | awk '{print $9}'`(仅输出文件名) | | **实时监控** | `tail -f access.log | grep 404`(实时监控日志中的404错误) | | **多级处理** | `dmesg | grep -i "usb" | less`(分页查看USB设备日志) | --- #### **五、管道与重定向的区别** | **特性** | **管道(`|`)** | **重定向(`>`/`<`)** | |----------------|---------------------------------------|----------------------------------| | **方向** | 命令间传递数据 | 命令与文件间传递数据 | | **输入源** | 前一命令的输出 | 文件内容或输出到文件 | | **典型用途** | `cmd1 | cmd2` | `cmd > file` 或 `cmd < file` | --- #### **六、优缺点** - **优点**: - **高效**:避免中间文件,减少磁盘I/O。 - **灵活**:支持任意命令组合(如`grep`、`sort`、`awk`等)。 - **缺点**: - **单向流动**:只能从左到右传递数据。 - **实时性**:数据流处理完成后无法回溯。 --- #### **七、扩展:命名管道(FIFO)** - **特点**:通过文件系统创建的管道(`mkfifo`命令生成),允许无关进程通信。 - **示例**: ```bash mkfifo my_pipe # 创建命名管道 echo "Hello" > my_pipe # 进程A写入数据 cat < my_pipe # 进程B读取数据 ``` --- #### **八、速记总结** ``` 管道一根竖线连,命令协作数据传; 前输后入不存盘,过滤统计随手编; 单向流动效率高,命名管道更神通。 ``` 掌握管道后,可通过组合简单命令完成复杂任务,是Linux高效操作的必备技能!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值