Linux进程间通信之匿名管道

Linux进程间通信之匿名管道



0.思考题

  • 全局变量,父子进程之间是否可以相互访问?
  • 父子进程在内存占用的是否为同一块内存空间?

一般而言,我们可以认为每个进程享有独立的内存空间(如果子进程只读数据Linux 系统会优化使得父子进程占据同一块区域,这一情况不在我们考虑范围之内)。
因为,各自占据一块内存,因此每个进程都有一个 4G 虚拟内存(32位系统),即每个进程有自己的全局区堆区栈区等。由此,父子进程是无法相互访问各自的全局变量(因为各自有自己的全局区)。

  • 那个,如果父子进程进程之间如何进数据传递呢?

常用的进程间数据传递方法如下:管道消息队列信号量共享内存等。
本文,余下章节将介绍基于管道的进程间数据通信。

1.基本概念

由于连个进程各自拥有自己独立的内存空间,因此无法直接进行数据传递。类似于交换两个变量需要中间变量,同理,我们可以找到一个中转站,使用中转站来进行数据传递。此中转站需要两个两个进程都可以访问到。
管道技术,就是基于上述基本思路。何为管道?类似于现实中的管道,此处的管道,即为两个进程之间可以进行数据传递的一条通道。
管道的本质是内核中的一段缓冲区,即我们上文所述的中转站
这段缓冲区,由两个文件描述符引用,一个文件描述如Pipefd[1]负责写数据,一个文件描述符如Pipefd[0]负责读数据。
在这里插入图片描述


2.管道函数 pipe 介绍

2.1 函数原型

#include <unistd.h>
int pipe(int pipefd[2]);

2.2 函数功能

pipe 函数用来创建一个有血缘关系的进程之间通信管道.
何为有血缘关系的进程?
父子进程兄弟进程等。

2.3 形参解释

形参 int pipefd[2] 是一个整数数组,其本质是一个传出参数。

  • pipefd[0]:管道端文件描述符
  • pipefd[1]:管道端文件描述符

2.4 返回值解释

  • 成功返回 : 0
  • 失败返回:-1,并且设置 相应的errno

3.案例程序之父子进程通信

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

int main(void)
{
    int result = -1;    // 创建管道结果
    int fd[2];          // 管道创建后得到的文件描述符
    result = pipe(fd);  // 创建管道
    if(-1 == result){
        perror("pipe");
        return -1;
    }
    pid_t pid = fork();
    if(-1 == pid){
        perror("fork");
        return -1;
    }else if(0 == pid){
        // 子进程
        // 为了使得子进程负责读,需要关闭子进程中 pipe 的写端
        close(fd[1]);
        // 循环读父进程的数据
        char buf[1024] = {0};
        size_t count = 1024;
        int ret = read(fd[0], buf, count);
        // 将读到数据写到 终端
        //write(STDOUT_FILENO, buf, strlen(buf));
        printf("%s", buf);
        close(fd[0]);
    }else{
        // 父进程
        // 我们指定父进程只进行写数据,因此我们要关闭 pipe 的读端
        close(fd[0]);
        // 将 buf 中的内容写入到 管道写端
        char buf[1024] = "hello pipe test.\n";
        int ret = write(fd[1], buf, strlen(buf));
        if(-1 == ret){
			perror("write");
            return -1;
        }
        printf("The parent is over.\n");
    }
    return 0;
}        

程序运行结果:
在这里插入图片描述


4.相关文章直达

Linux进程间通信之命名管道(点击直达)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值