Qt多进程(十)匿名管道Pipe

前言

相对于有名管道或命名管道,经常一起对比的就是无名管道或匿名管道。之前在使用QProcess的时候有了解到它底层也是用匿名管道实现的,但在Linux中匿名管道还可以用更原始的方式去写,顺便再接触一下fork启动子进程的方式。

匿名管道或无名管道吧,虽然没有名字,但本质是还是靠着文件,也就是文件操作符来实现通信的。毕竟在Linux中,一切皆文件嘛。

一、匿名管道

核心特点:

1.只能用于父子进程通信 (因为子进程通过 fork() 继承父进程的文件描述符)

2.创建时返回两个文件描述符 :一个读端(read end),一个写端(write end)

3.单向通信 :数据从写端进,从读端出

4.内核自动管理缓冲区(通常 64KB)

二、代码示例

先附上代码:

cpp 复制代码
#include <unistd.h>
#include <sys/wait.h>
#include <stdio.h>
#include <string.h>

int main() {
    int fd[2];  // fd[0] = 读端, fd[1] = 写端
    pid_t pid;

    // 创建匿名管道
    if (pipe(fd) == -1) {
        perror("pipe failed");
        return 1;
    }

    // 创建子进程
    pid = fork();
    if (pid == -1) {
        perror("fork failed");
        return 1;
    }

    if (pid == 0) {
        // ===== 子进程:读取数据 =====
        char buffer[256];
        close(fd[1]);  // 关闭写端(子进程不需要写)

        ssize_t bytes = read(fd[0], buffer, sizeof(buffer) - 1);
        if (bytes > 0) {
            buffer[bytes] = '\0';  // 确保字符串结尾
            printf("Child process received: %s\n", buffer);
        }

        close(fd[0]);
        return 0;
    } else {
        // ===== 父进程:发送数据 =====
        const char *msg = "Hello from parent process via anonymous pipe!";
        close(fd[0]);  // 关闭读端(父进程不需要读)

        write(fd[1], msg, strlen(msg));
        close(fd[1]);

        // 等待子进程结束
        wait(NULL);
        printf("Parent process finished.\n");
        return 0;
    }
}

运行效果:

这里说一下代码细节和自己理解。

1.int fd2存储的是一对文件操作符,包含读和写。创建管道的时候需要传递,成功返回0,不成功返回-1。

后续子进程会关闭写端(close(fd[1);),父进程会关闭读端(close(fd[0);),我一开始没搞懂这到底是怎么对应上的。

其实何为管道 呢?

用过水管来比喻,fd0 和 fd1 不是两个独立的文件,而是同一个内核管道对象的两个"端口"------一个只读,一个只写。

它们通过内核中的同一个管道缓冲区连接起来,就像一根水管的两端。

这样想,思路似乎就清晰多了。

2.fork()

这是Linux下创建进程的核心方法。它会复制当前进程,生成一个几乎一模一样的子进程。

也就是说,虽然我们在终端中只运行了一个程序,但在fork()这句话之后,实际上就已经产生了两个进程了。

在子进程中,pid = fork()的返回值是0,而父进程则是子进程的PID。所以接下来的代码中就以pid来进行父子进程的划分了。

3.子进程中的read是阻塞式的,它会等待父进程write了之后,才会被激活。

4.父进程中的wait(NULL);是为了等待子进程的街胡思。也就是说,得先子进程结束,父进程才能结束。如果不这样,子进程结束后会变成僵尸进程,占用进程表项。

三、总结

最后对比一下命名管道和匿名管道吧!

相关推荐
2601_966949657 小时前
为什么量化策略需要大量历史股票数据?从回测可信度理解数据规模
开发语言·python·数据分析·pandas·量化交易·股票数据·quantdash
niucloud-admin7 小时前
JAVA V6 多商户商城 开发文档——插件目录结构
java·开发语言
滕州市燕猫虎计算机科技工作室个体工商户7 小时前
Java锁
java·开发语言
多加点辣也没关系8 小时前
JavaScript|第31章:表单与控件
开发语言·javascript·ecmascript
菜鸟~noob2338 小时前
【电子战】 第09篇:阵列信号处理——波束形成、MVDR、MUSIC【含matlab代码】
开发语言·matlab·信号处理
ocean21038 小时前
2025-2026年Python面试高频知识点洞察
开发语言·python·面试·python八股文
零依赖极客8 小时前
Day 6·1 ARMv8.2 dotprod——vdotq_s32 一条指令做 4 个点积
c语言·开发语言·人工智能·矩阵·arm·vllm
新时代牛马10 小时前
cyclictest 毛刺从哪来?从ftrace、latencytop、perf到IRQ/调度延迟定位
android·开发语言·python·kotlin
三84410 小时前
Java 模板注入(FreeMarker) · 02 · 模板引擎与 FreeMarker 语法
java·开发语言·web安全·freemarker
IvanCodes11 小时前
Python 基础语法(七):推导式与常见遍历写法
开发语言·python