首页 > 系统相关 >Linux IPC:管道与FIFO汇总整理

Linux IPC:管道与FIFO汇总整理

时间:2025-01-11 10:04:35浏览次数:3  
标签:IPC read bytes FIFO 管道 Linux 进程 include

管道(Pipes)和先进先出(FIFOs,也称为命名管道)都是Linux中用于进程间通信(IPC)的机制。它们允许数据从一个进程流向另一个进程,类似于命令行中的管道操作符 |。下面详细介绍这两种机制以及如何使用它们。

2a430394f0f240d3b89830522fee97bf.jpeg

管道 (Pipes)

管道是一种特殊的文件,它允许数据从一个进程(通常称为生产者)流向另一个进程(通常称为消费者)。管道是半双工的,意味着数据只能单向流动。

特点

  • 管道存在于内存中,不是真正的文件系统对象。
  • 管道只能用于具有亲缘关系的进程之间,通常是父子进程。
  • 管道是半双工的,即数据只能在一个方向上流动。
  • 管道的容量有限,当写入的数据超过管道的容量时,写入操作会被阻塞,直到消费者读取了一些数据。

创建管道

  • pipe():
    • int pipe(int pipefd[2]): 创建一个管道。
    • 参数pipefd是一个数组,包含两个文件描述符,第一个用于读取,第二个用于写入。

示例代码

以下是一个简单的例子,展示了如何使用管道在父子进程中传递数据:

1#include <unistd.h>
2#include <stdio.h>
3#include <stdlib.h>
4#include <string.h>
5#include <sys/wait.h>
6
7int main() {
8    int pipefd[2];
9    pid_t pid;
10
11    // 创建管道
12    if (pipe(pipefd) == -1) {
13        perror("pipe");
14        exit(EXIT_FAILURE);
15    }
16
17    // 创建子进程
18    pid = fork();
19    if (pid < 0) {
20        perror("fork");
21        exit(EXIT_FAILURE);
22    } else if (pid == 0) {  // 子进程
23        close(pipefd[1]);  // 关闭写端
24        char buffer[1024];
25        ssize_t bytes_read = read(pipefd[0], buffer, sizeof(buffer) - 1);
26        if (bytes_read == -1) {
27            perror("read");
28            exit(EXIT_FAILURE);
29        }
30        buffer[bytes_read] = '\0';  // 确保字符串以空字符结尾
31        printf("子进程读取: %s\n", buffer);
32        close(pipefd[0]);
33        exit(EXIT_SUCCESS);
34    } else {  // 父进程
35        close(pipefd[0]);  // 关闭读端
36        const char *message = "Hello, World!";
37        ssize_t bytes_written = write(pipefd[1], message, strlen(message));
38        if (bytes_written == -1) {
39            perror("write");
40            exit(EXIT_FAILURE);
41        }
42        close(pipefd[1]);
43
44        // 等待子进程结束
45        wait(NULL);
46    }
47
48    return 0;
49}

FIFO (Named Pipes)

FIFO 或命名管道类似于管道,但它们是文件系统中的特殊文件,因此可以被任何进程访问。这意味着它们可以用于没有亲缘关系的进程之间进行通信。

特点

  • FIFO 是持久性的,即使创建它的进程不再存在,FIFO 仍然存在。
  • FIFO 可以被任何进程打开和使用,而不仅仅是父子进程。
  • FIFO 也是半双工的,即数据只能在一个方向上流动。
  • FIFO 的容量同样有限,当写入的数据超过 FIFO 的容量时,写入操作会被阻塞,直到消费者读取了一些数据。

创建 FIFO

  • mkfifo():
    • int mkfifo(const char *pathname, mode_t mode): 创建一个 FIFO。
    • 参数pathname指定 FIFO 的路径名,mode指定权限掩码。

示例代码

以下是一个简单的例子,展示了如何使用命名管道在两个进程之间传递数据:

1#include <unistd.h>
2#include <stdio.h>
3#include <stdlib.h>
4#include <string.h>
5#include <fcntl.h>
6#include <sys/stat.h>
7
8#define FIFO_NAME "/tmp/myfifo"
9
10int main() {
11    int filedes;
12    char buffer[1024];
13
14    // 创建 FIFO
15    if (mkfifo(FIFO_NAME, S_IRUSR | S_IWUSR) == -1) {
16        if (errno != EEXIST) {
17            perror("mkfifo");
18            exit(EXIT_FAILURE);
19        }
20    }
21
22    // 读取进程
23    filedes = open(FIFO_NAME, O_RDONLY);
24    if (filedes == -1) {
25        perror("open");
26        exit(EXIT_FAILURE);
27    }
28
29    ssize_t bytes_read = read(filedes, buffer, sizeof(buffer) - 1);
30    if (bytes_read == -1) {
31        perror("read");
32        exit(EXIT_FAILURE);
33    }
34    buffer[bytes_read] = '\0';  // 确保字符串以空字符结尾
35    printf("读取进程: %s\n", buffer);
36    close(filedes);
37
38    // 写入进程
39    filedes = open(FIFO_NAME, O_WRONLY);
40    if (filedes == -1) {
41        perror("open");
42        exit(EXIT_FAILURE);
43    }
44
45    const char *message = "Hello, World!";
46    ssize_t bytes_written = write(filedes, message, strlen(message));
47    if (bytes_written == -1) {
48        perror("write");
49        exit(EXIT_FAILURE);
50    }
51    close(filedes);
52
53    return 0;
54}

注意事项

  • 在使用管道或 FIFO 之前,确保检查文件描述符的有效性。
  • 当使用 FIFO 时,确保至少有一个进程已经打开了 FIFO 的读端或写端,否则打开操作可能会失败。
  • 在使用完管道或 FIFO 后,记得关闭文件描述符以释放资源。
  • 在创建 FIFO 之后,确保在不再需要时删除它以释放文件系统资源。
  • 跨进程通信时,确保处理好同步问题,避免数据竞争或死锁。

管道和 FIFO 都是非常有用的进程间通信工具,它们可以简化数据在进程之间的传输过程。理解和熟练掌握这些机制对于编写可靠、高效的多进程程序非常重要。

 

标签:IPC,read,bytes,FIFO,管道,Linux,进程,include
From: https://blog.csdn.net/suifengme/article/details/140753445

相关文章

  • wacom 手写笔linux驱动代码
    /*Wacomprotocol4serialtabletdriverThisprogramisfreesoftware;youcanredistributeitand/ormodifyitunderthetermsoftheGNUGeneralPublicLicenseaspublishedbytheFreeSoftwareFoundation;eitherversionof2oftheLicense,or(a......
  • Arch Linux Code-OSS里面空格显示太小了
    Code-OSS是linux版本的vscode,发现在ArchLinuxCode-OSS里面空格显示太小了,网上找了很多方法,有一个ubuntu用户说是第三个一定“第三个一定是monospace”,我无意中发现,其实就是字体的问题,只要你添加的字体足够多就行了,先看一下默认字体状态下的字体显示,就是一个tab确实是4个空......
  • 文件“硬连接”是 Linux 操作系统的缺陷吗,为啥跟微软的文件“软连接”,不一致?
    故事时间假设有个女孩叫 小文件:小文件在硬盘上有个家(inode),地址是2号楼304。这个家里存着她的全部信息:身高、体重(划掉)、兴趣爱好等等。硬链接:相当于【身份证】假如小文件要办两个身份证(硬链接),每个身份证都记录着:这个人住在2号楼304。无论用哪个身份证,都能找到本人只要......
  • Linux开机启动过程
    Linux系统的开机启动过程是一个复杂但有序的序列,它确保系统从硬件初始化到提供一个完全功能的操作环境。以下是这个过程的详细步骤:BIOS/UEFI启动:当计算机加电时,首先执行的是基本输入输出系统(BIOS)或更现代的统一可扩展固件接口(UEFI)。BIOS/UEFI主要负责硬件自检(POST,Power-O......
  • 在Linux中,如何进行系统性能的持续监控?
    在Linux中进行系统性能的持续监控,需要综合运用各种命令行工具和图形化界面工具,以及自动化脚本和第三方监控平台。以下是实现持续监控的一些建议步骤和工具:1.使用基础命令行工具实时查看top:实时查看CPU使用率、内存占用、运行中的进程等基本信息。htop(一个增强版的top):提供......
  • [Linux] 包管理器之【APT】
    序续:《[Linux]Linux中安装软件的方式?-博客园/千千寰宇》《[Linux]包管理器之综述【RPM/DPKG|YUM/APT】-博客园/千千寰宇》概述:包管理器APTAPT:AdvancedPackagingTool(现名)解释:AdvancedPackagingTool(apt),作为原始包管理器DPKG的前端包管理工具(在线包管......
  • 想在linux平台拥有和vs一样的体验模式吗?只需配置一下你的vim便可以轻松达到,让你日常
            ......
  • Linux基础——kail工具
    一、nmap主机发现和端口扫描1、nmap指定源端口eth0发送扫描┌──(root㉿kali2024)-[~]└─#nmap192.168.190.110-eeth0StartingNmap7.94SVN(https://nmap.org)at2025-01-1019:56HKTNmapscanreportfor192.168.190.110Hostisup(0.0018slatency).Nots......
  • day13-Linux系统用户管理知识2
    1.passwd1.1更改密码[root@oldboy~]#passwd更改用户root的密码。新的密码:无效的密码:密码少于8个字符重新输入新的密码:passwd:所有的身份验证令牌已经成功更新。#修改其他用户的密码[root@oldboy~]#passwdoldboy更改用户oldboy的密码。新的密码......
  • Linux连接(NFS)群晖NAS遇到的问题(最终选SetGID+umask)
     说明:公司在寻找存储服务器,分布式太贵,后来找来厂家提供服务器试用一段时间,可以的话再买更高型号的来用,此文章记录整个过程,可能比较杂,等以后有时间再来整理吧。需求:想要在服务器之间共同访问并操作这里的存储,并且还要再Windows上查看(需求又改了Windows上也会做增删改的操作。。)......