【linux】进程间通信-管道

1. 前言

进程间通信(InterProcess Communication, IPC)方式包括:管道、FIFO、消息队列、信号量以及共享存储。

本篇学习笔记只记录管道通信。

2. 管道介绍

2.1 管道原理

管道是UNIX系统IPC的最古老形式,所有UNIX系统都提供此种通信机制。管道有两种局限性:

  • 半双工的,即数据只能在一个方向上流动。现在有些系统支持全双工管道。
  • 管道只能在具有公共祖先的两个进程之间使用。通常,一个管道由一个进程创建,在进程调用fork之后,这个管道就能在父进程和子进程之间使用了。

每当在管道中键入一个命令序列,让shell执行,shell都会为每一条命令单独创建一个进程,然后用管道将前一条命令进程的标准输出与后一条命令的标准输入相连接。

个人理解:经常用的命令ps -ef | grep 66750查看进程信息,shell做的工作如下:

  1. ps -ef命令创建一个进程
  2. grep 66750命令创建一个进程
  3. 用管道将ps -ef 的输出连接到grep 66750的输入,所以这儿的管道是shell创建的。
  4. ps -ef命令的输出会被保存到内存里。

从下图可以看出两个子进程ps -ef grep 66750被创建出来了,并且是相同的父进程bash
管道

管道是通过调用pipe函数创建的:

#include <unistd.h>
int pipe(int fd[2]);
返回值:若成功,返回0, 若出错,返回-1

参数fd为两个文件描述符,f[0]为读而打开,fd[1]为写而打开。fd[1]的输出是fd[0]的输入。

2.2 管道例子

2.2.1 例子1,创建一个从父进程到子进程的管道,并且父进程经由该管道向子进程传送数据。

#include "apue.h"

int main(void)
{
    int n;
    int fd[2];
    pid_t pid;
    char line[MAXLINE];

    // 创建管道
    if (pipe(fd) < 0)
        err_sys("pipe error");
    // 创建进程
    if ((pid = fork()) < 0) {
        err_sys("fork error");
    } else if (pid > 0){        /* 父进程 */
        // 关闭父进程的读文件描述符
        printf("parent pid: %d\n", pid);
        close(fd[0]);
        write(fd[1], "hello world\n", 12);
        printf("parent write finish!\n");
    } else {                    /* pid == 0为子进程 */
        // 关闭子进程的写文件描述符
        printf("chaild pid: %d\n", pid);
        close(fd[1]);
        // 从读文件描述符里获取内容
        n = read(fd[0], line, MAXLINE);
        // 写到标准输出里
        write(STDOUT_FILENO, line, n);
        printf("child read finish and show to stdout!\n");
    }
    exit(0);
}

在这里插入图片描述

2.2.2 例子2,每次一页地显示已产生的输出,将文件复制到分页程序
原理可分如下几步:
1) 父进程创建管道
2)父进程把文件读取出来写入到文件描述符fd[1]中
3)子进程调用execl()函数,该函数会调用分页程序/bin/more,将管道中的内容输出出来。

代码参考:将文件复制到分页程序

运行效果:
成功将文件/tmp/test/test.c内容输出出来了
在这里插入图片描述

3. 参考资料

3.1 《UNIX环境高级编程第3版》 P430-P435

3.2 Linux 的进程间通信:管道 https://zhuanlan.zhihu.com/p/58489873

3.3 Unix环境高级编程——解决第一个问题“apue.h: No such file or directory” : https://blog.csdn.net/qq_41899773/article/details/107376991

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值