linux进程----匿名管道和命名管道

news2024/12/29 9:50:30

linux进程----匿名管道和命名管道

在Linux中,管道是用于进程间通信的一种机制,可以分为两种类型:匿名管道(也称为匿名fifo)和命名管道(也称为命名fifo或named pipe)。

匿名管道(Anonymous Pipe)

匿名管道是一种半双工的通信机制,它允许一个进程的输出直接传递给另一个进程的输入。匿名管道通常由管道符(|)在命令行中创建。

  1. 创建匿名管道
    command1 | command2
    
    在这个例子中,command1 的输出会被传递给 command2 的输入。
  2. 特点
    • 匿名管道没有名称,因此无法在文件系统中直接访问。
    • 它只能用于父子进程之间,或者兄弟进程之间(通过fork)。
    • 它是一次性的,即一旦两个进程完成通信,管道就会消失。在这里插入图片描述

命名管道(Named Pipe)

命名管道是一种全双工的通信机制,它允许多个进程之间进行通信。命名管道在文件系统中有一个名称,可以像文件一样被访问。

  1. 创建命名管道
    mkfifo filename
    
    或者在命令行中使用:
    command1 | tee >(mkfifo filename) | command2
    
    在这个例子中,command1 的输出被传递给 tee 命令,后者将输出同时写入一个匿名管道和一个文件(这里通过命名管道)。command2 的输入则来自这个匿名管道。
  2. 特点
    • 命名管道在文件系统中有一个名称,可以在多个进程之间共享。
    • 它允许全双工通信,即可以同时进行读写操作。
    • 它具有持久性,即即使创建它的进程已经结束,管道仍然存在,直到最后一个使用它的进程结束。在这里插入图片描述

使用示例

  • 匿名管道
    ls | grep "file"
    
    在这个例子中,ls 命令的输出会被传递给 grep 命令的输入。
  • 命名管道
    mkfifo myfifo
    cat > myfifo
    cat < myfifo
    
    在这个例子中,首先创建了一个命名管道 myfifo。然后,一个进程通过 cat > myfifo 将数据写入管道,另一个进程通过 cat < myfifo 从管道中读取数据。
    这两种管道机制都是Linux中常用的进程间通信方式,它们各有优缺点,可以根据具体需求选择合适的方法。

匿名管道(Anonymous Pipe)

匿名管道是一种简单的进程间通信机制,它允许一个进程的输出直接传递给另一个进程的输入。匿名管道是半双工的,这意味着数据只能单向传输。

工作原理:
  1. 创建匿名管道
    • 当你在命令行中使用管道符 | 连接两个命令时,实际上是在创建一个匿名管道。
    • 第一个命令的输出被重定向到匿名管道中,而匿名管道的输出则被重定向到第二个命令的输入。
  2. 数据传输
    • 第一个命令开始执行,其输出被写入匿名管道。
    • 第二个命令开始执行,它从匿名管道中读取数据作为输入。
  3. 管道消失
    • 一旦两个命令执行完毕,匿名管道就会被销毁。
特点:
  • 单向通信:匿名管道只能用于单向通信,即一个进程的输出传递给另一个进程的输入。
  • 半双工:数据只能单向传输,不能同时读写。
  • 一次性的:匿名管道是一次性的,一旦两个进程完成通信,管道就会消失。
  • 父子进程或兄弟进程间通信:匿名管道通常用于父子进程之间或通过fork创建的兄弟进程之间。

命名管道(Named Pipe)

命名管道是一种全双工的进程间通信机制,它允许多个进程之间进行通信。命名管道在文件系统中有一个名称,可以像文件一样被访问。

工作原理:
  1. 创建命名管道
    • 使用 mkfifo 命令创建一个命名管道,或者在命令行中通过 tee 命令创建匿名管道,然后重定向到命名管道。
  2. 数据传输
    • 进程可以通过 cat > named_pipe 将数据写入管道,也可以通过 cat < named_pipe 从管道中读取数据。
  3. 持久性
    • 即使创建它的进程已经结束,命名管道仍然存在,直到最后一个使用它的进程结束。在这里插入图片描述
特点:
  • 全双工通信:命名管道允许全双工通信,即可以同时进行读写操作。
  • 持久性:命名管道在文件系统中有一个名称,可以在多个进程之间共享,并且具有持久性。
  • 灵活性:命名管道可以被任何进程读写,不受父子进程或兄弟进程的限制。

使用示例:

  • 匿名管道
    ls | grep "file"
    
    在这个例子中,ls 命令的输出会被传递给 grep 命令的输入。
  • 命名管道
    mkfifo myfifo
    cat > myfifo
    cat < myfifo
    
    在这个例子中,首先创建了一个命名管道 myfifo。然后,一个进程通过 cat > myfifo 将数据写入管道,另一个进程通过 cat < myfifo 从管道中读取数据。
    匿名管道和命名管道都是Linux中常用的进程间通信方式,它们各有优缺点,可以根据具体需求选择合适的方法。匿名管道适用于简单的单向通信,而命名管道适用于复杂的双向通信和多进程间通信。

管道所用的函数在这里插入图片描述

在Linux系统中,管道(Pipe)的创建和使用涉及到一些特定的系统调用和函数。以下是创建和使用管道的一些关键函数和概念:

创建管道

在Linux中,可以使用 pipe 系统调用来创建一个匿名管道。这个函数会返回两个文件描述符:一个用于读取管道,另一个用于写入管道。

#include <unistd.h>
int pipe(int fd[2]);
  • fd[2]:这是一个包含两个整数的数组,第一个整数用于读取,第二个整数用于写入。
  • 返回值:成功时返回0,失败时返回-1。

使用管道

一旦管道被创建,就可以通过以下方式来使用它:

  1. 写入管道
    #include <unistd.h>
    int write(int fd, const void *buf, size_t count);
    
    • fd:文件描述符,用于写入管道。
    • buf:指向要写入数据的缓冲区的指针。
    • count:要写入的字节数。
  2. 读取管道
    #include <unistd.h>
    int read(int fd, void *buf, size_t count);
    
    • fd:文件描述符,用于从管道中读取数据。
    • buf:指向读取数据的缓冲区的指针。
    • count:最多可以读取的字节数。

关闭管道

在完成对管道的读写操作后,应该关闭相关的文件描述符。

#include <unistd.h>
int close(int fd);
  • fd:要关闭的文件描述符。

示例代码

以下是一个简单的C语言示例,展示了如何创建和使用管道:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main() {
    int fd[2];
    pipe(fd); // 创建匿名管道
    // 子进程将执行的代码
    if (fork() == 0) {
        close(fd[0]); // 关闭读端
        write(fd[1], "Hello, World!", 14); // 写入管道
        close(fd[1]); // 关闭写端
        exit(0);
    }
    // 父进程将执行的代码
    close(fd[1]); // 关闭写端
    char buf[15];
    read(fd[0], buf, 14); // 从管道中读取数据
    printf("Received: %s\n", buf); // 打印接收到的数据
    close(fd[0]); // 关闭读端
    return 0;
}

在这个示例中,子进程向管道写入数据,而父进程从管道中读取数据。
请注意,这些函数和概念是Linux编程的基础,对于深入理解Linux系统编程非常重要。

在这里插入图片描述

匿名管道函数 命名管道函数 父子进程 不同进程通信

在Linux中,匿名管道和命名管道是进程间通信(IPC)的两种常见机制。它们用于在进程之间传递数据,特别是在父子进程之间或相关的进程之间。

匿名管道(Anonymous Pipe)

匿名管道是一种半双工的通信方式,用于在两个进程之间传输数据。匿名管道是在两个命令之间使用管道符(|)时自动创建的,不需要显式地创建。

创建和操作匿名管道:
  1. 创建:当一个命令的输出被管道符(|)连接到另一个命令的输入时,就会创建一个匿名管道。
  2. 读写
    • 第一个命令的输出被写入匿名管道。
    • 第二个命令的输入从匿名管道中读取。
  3. 关闭:当管道两端的进程都完成了读写操作后,管道会自动关闭。
示例:
ls | grep "file"

在这个例子中,ls 命令的输出被传递给 grep 命令的输入。

命名管道(Named Pipe)

命名管道是一种全双工的通信方式,可以在多个进程之间传输数据。它通过文件系统的路径进行访问,因此可以被多个进程共享。

创建和操作命名管道:在这里插入图片描述
  1. 创建:使用 mkfifo 命令或通过命令行创建匿名管道并重定向到命名管道。
  2. 读写
    • 进程可以通过 cat > named_pipe 将数据写入管道。
    • 进程可以通过 cat < named_pipe 从管道中读取数据。
  3. 持久性:即使创建它的进程已经结束,命名管道仍然存在,直到最后一个使用它的进程结束。
示例:
mkfifo myfifo
cat > myfifo
cat < myfifo

在这个例子中,首先创建了一个命名管道 myfifo。然后,一个进程通过 cat > myfifo 将数据写入管道,另一个进程通过 cat < myfifo 从管道中读取数据。

父子进程和不同进程通信:

  • 父子进程:匿名管道通常用于父子进程之间的通信。当一个进程通过 fork 创建一个子进程时,匿名管道可以用来在两个进程之间传递数据。
  • 不同进程:命名管道可以用于多个相关进程之间的通信。由于它可以通过文件系统的路径进行访问,因此可以被多个进程共享。
    在实际应用中,匿名管道和命名管道都是非常重要的IPC机制,它们各自适用于不同的场景。匿名管道适用于简单的单向通信,而命名管道适用于复杂的双向通信和多进程间通信。

代码示例

以下是一个简单的Python代码示例,展示了如何在两个进程之间使用命名管道进行通信。这个例子使用了os.fork()函数来创建一个子进程,并使用os.open()os.write()函数来创建和写入命名管道。

import os
import time
# 创建命名管道
named_pipe_path = '/tmp/my_named_pipe'
os.makedirs('/tmp', exist_ok=True)
os.mkfifo(named_pipe_path)
# 父进程代码
def parent_process():
    # 打开命名管道用于写入
    with os.open(named_pipe_path, os.O_WRONLY) as pipe:
        # 写入数据到命名管道
        os.write(pipe, b'Hello from parent\n')
        time.sleep(2)  # 等待子进程读取
        os.write(pipe, b'Parent done\n')
# 子进程代码
def child_process():
    # 打开命名管道用于读取
    with os.open(named_pipe_path, os.O_RDONLY) as pipe:
        # 读取数据从命名管道
        data = os.read(pipe, 1024)
        print(f'Child received: {data.decode("utf-8")}')
        time.sleep(1)  # 等待父进程写入
        data = os.read(pipe, 1024)
        print(f'Child received: {data.decode("utf-8")}')
# 创建子进程
if os.fork() == 0:
    child_process()
else:
    parent_process()

在这个例子中,父进程会创建一个名为 my_named_pipe 的命名管道,并在其中写入一些数据。子进程会打开同一个管道并从中读取数据。
请注意,这个例子需要在支持命名管道的环境中运行,并且需要相应的权限来创建和访问命名管道。此外,os.mkfifo() 函数在某些系统上可能需要管理员权限,因此你可能需要使用 sudo 命令来运行这个脚本。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1991521.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何解决整数溢出问题?

1、问题解析 当以整数数据类型&#xff08;包括字节、短、长和其他类型&#xff09;存储的值过大&#xff08;大于变量可容纳的最大值&#xff09;的值时&#xff0c;将发生整数溢出&#xff08;或环 绕&#xff09;。整数的最高有效位丢失&#xff0c;而其余值则相对于最小值…

Centos安装OpenSearch

Centos安装OpenSearch 下载并安装OpenSearch下载OpenSearch RPM包导入公共GNU Privacy Guard&#xff08;GPG&#xff09;密钥。此密钥验证您的OpenSearch实例是否已签名安装RPM包安装完设置开机自启动OpenSearch启动OpenSearch验证OpenSearch是否正确启动 测试OpenSearch向服务…

【lvs】超干货,包含理论+实验(详细步骤)

lvs理论部分 LVS&#xff08;Linux Virtual Server&#xff09;是Linux虚拟服务器的简称&#xff0c;是一个基于Linux操作系统的虚拟服务器集群系统。LVS主要用于实现负载均衡和高可用性&#xff0c;通过将客户端的请求分发到多台后端服务器上&#xff0c;从而提高整体服务的处…

JSON + AJAX + ThreadLocal

JSON数据交换 规则 JSON对象和字符串转换 <script type"text/javascript">var jsonPerson {"name": "jack","age": 20}console.log(jsonPerson);var strPerson JSON.stringify(jsonPerson);//对jsonPerson没有影响console.lo…

文件系统 --- 软硬链接

序言 经过上一篇的学习 在磁盘中的文件&#xff0c;我们大致了解了磁盘的物理结构&#xff0c;逻辑抽象结构以及文件在磁盘上的存储方式。在这篇文章中&#xff0c;我们会基于上一篇文章的部分知识点来介绍软链接&#xff0c;硬链接。 1. 软链接 1.1 软链接的概念 软链接是一个…

vue3+vite+ts 颜色选择器组件支持颜色吸取,透明度

ciw-color-picker-vue&#xff1a; vue3 vite ts 颜色选择器,支持颜色吸取,透明度&#xff0c;与浏览器原生颜色选择器相似,与饿了么颜色选择器相似 使用了ciw-color-picker-vue npm i ciw-color-picker-vue 安装 npm i ciw-color-picker-vue 全局引入方式 main.ts 或 m…

光伏检测室外气象站的重要性

在光伏产业的快速发展中&#xff0c;光伏检测室外气象站的重要性日益凸显。它不仅是光伏电站运维管理的“眼睛”&#xff0c;更是确保电站高效、稳定运行的关键因素。 首先&#xff0c;光伏检测室外气象站能够实时、准确地监测多种关键气象要素&#xff0c;如太阳辐射、风速、风…

【中间件】Redis从入门到精通-黑马点评综合实战

文章目录 一&#xff1a;Redis基础1.Redis是什么2.初识Redis3.Redis的数据结构A.通用命令B.String类型C.Key的层级格式D.Hash类型E.List类型F.Set类型G.SortedSet类型 二&#xff1a;Redis的Java客户端1.JedisA.引入依赖B.建立连接C.测试JedisD.释放资源 2.Jedis连接池3.Spring…

MM 13 -采购- 退货

思维导图 说明 情形1 直接冲销物料凭证 102 情形2 返货部分交货 情形3 退货PR贷项凭证 情形1 适用于已收货未开票&#xff0c;或者发票还可冲销的当月&#xff0c;冲销物料凭证所有数量 情形2 适用于跟情形1 一样&#xff0c;只是可以修改退货数量 情形3 如果已经跨越…

html+css+js网页设计字节跳动11个页面带js 效果很多

htmlcssjs网页设计字节跳动11个页面带js 效果很多 ui还原度100% 网页作品代码简单&#xff0c;可使用任意HTML编辑软件&#xff08;如&#xff1a;Dreamweaver、HBuilder、Vscode 、Sublime 、Webstorm、Text 、Notepad 等任意html编辑软件进行运行及修改编辑等操作&#xff0…

笔试练习day3

目录 BC149 简写单词题目解析代码 dd爱框框题目解析解析代码方法一暴力解法方法二同向双指针(滑动窗口) 除2!题目解析解法模拟贪心堆 感谢各位大佬对我的支持,如果我的文章对你有用,欢迎点击以下链接 &#x1f412;&#x1f412;&#x1f412; 个人主页 &#x1f978;&#x1…

【网络安全】玲珑安全第四期

鉴于玲珑安全漏洞挖掘前三期课程取得的优异成绩和获得的强烈反响,我们决定启动玲珑安全第四期漏洞挖掘培训计划。 文章目录 往期学员收获基础学员报喜(部分)课程反馈第四期课程课程内容免费课程往期学员收获 第一期课程总结及学员收获:->点我查看第一期学员收获<- …

leetcode 图论专题——(dfs+bfs+并查集 回顾)

DFS、BFS 回顾&#xff08;C语言代码&#xff09; map[i][j]里记录的是i点和j点的连接关系 基本DFS&#xff1a; int vis[101],n,map[101][101]; void dfs(int t) {int i;vis[t]1;for(i0;i<n;i)//找对t点所有有关联的点——“找路”{if(vis[i]!0&&map[t][i]1)//有…

怎么将jar注册为windows系统服务详细操作

将spring boot项目编译成jar,注册为windows系统服务 在网上了解到,winsw这个开源项目,去github看了下,作者常年维护更新,文档齐全,拥有不少,自己写了个小demo体验了下还不错,然后又运行了一个晚上,没啥问题,遂决定采用它 开源地址 源库地址 https://github.com/winsw/winsw R…

string类简单的底层实现,了解string底层以及string的补充知识

string类的简单实现 头文件 #define _CRT_SECURE_NO_WARNINGS 1 #pragma once #include<iostream> #include<assert.h> using namespace std; namespace exprience {class string {public:typedef char* iterator;iterator begin(){return _str;}iterator end()…

IPython使用技巧详解:提高Python编程效率的利器

目录 一、IPython基础设置与启动 1.1 安装IPython 1.2 IPython的配置 二、IPython交互式编程体验 2.1 魔术命令(Magic Commands) 2.2 变量自动补全与文档查看 2.3 历史命令与快速访问 三、IPython高级功能 3.1 列表推导式与生成器表达式 3.2 枚举与压缩函数 3.3 L…

Java NIO(Non-blocking I/O)简单理解

Java NIO是Java平台中用于高效输入/输出&#xff08;I/O&#xff09;操作的一套新的API&#xff0c;与标准的Java I/O&#xff08;基于流的阻塞I/O&#xff09;不同&#xff0c;Java NIO提供了非阻塞式的I/O操作。 Java NIO 的核心组件 Java NIO主要由以下几个核心部分组成&a…

服务器网络不通排查方案

服务器网络不通排查方案 最近遇到了服务器上服务已经启动&#xff0c;但是在浏览器上无法访问的问题&#xff0c;记录一下排查流程 文章目录 服务器网络不通排查方案netstart排查网络连接信息netstat 命令netstat -aptn 命令 iptables总结 netstart排查网络连接信息 netstat …

【Linux进程篇】进程终章:POSIX信号量线程池线程安全的单例模式自旋锁读者写者问题

W...Y的主页 &#x1f60a; 代码仓库分享 &#x1f495; 前言&#xff1a;在之前的进程间通信时我们就讲到过信号量&#xff0c;他的本质就是一个计数器&#xff0c;用来描述临界资源的一个计数器。我们当时使用电影院的例子来说明信号量。电影院的座位被我们称为临界资源&a…

LVS集群实现四层负载均衡详解(以nat,dr模式为例)

目录 一、LVS集群的介绍 1、LVS 相关术语&#xff1a; 2、lvs工作原理 3、相关名词概念 4、lvs集群的类型 二、lvs的nat模式 1、介绍&#xff1a; 2、数据逻辑&#xff1a; 3、nat实验部署 环境搭建&#xff1a; 1、lvs中要去打开内核路由功能&#xff0c;实现网络互联…