2.10 进程间通信简介 2.11匿名管道概述 2.12父子进程通过匿名管道通信

2.10 进程间通信简介

进程间通讯概念

在这里插入图片描述
简称:
GUI:图像用户 接口
IDE:集成开发环境
API:应用程序接口

Linux进程间通信的方式

还有一种:内存映射

在这里插入图片描述

2.11匿名管道概述

匿名管道

在这里插入图片描述
ls获取一个目录中文件的列表,“|”创建管道服务,wc统计文件数目。

管道的特点

在这里插入图片描述

在这里插入图片描述
管道两端对应文件描述符
从现实应用角度理解单工、双工、半双工:
单工-遥控器发送数据给电视
双工-打电话
半双工-同一时刻,数据只能往一个方向发送,比如对讲机

为什么可以使用管道进行进程间通信

在这里插入图片描述
fork()创建子进程,父子进程共享文件描述符fd,文件描述符表处于内核中,上图中5指向管道读端,6指向管道写端。

管道的数据结构

在这里插入图片描述
环形队列(循环队列)逻辑上,可覆盖被读走数据的内存写入数据

匿名管道的使用

在这里插入图片描述

2.12父子进程通过匿名管道通信

创建匿名管道

/*
    #include <unistd.h>
    int pipe(int pipefd[2]);
        功能:创建一个匿名管道,用来进程间通信。
        参数:int pipefd[2] 这个数组是一个传出参数。
            pipefd[0] 对应的是管道的读端
            pipefd[1] 对应的是管道的写端
        返回值:
            成功 0
            失败 -1

    管道默认是阻塞的:如果管道中没有数据,read阻塞,如果管道满了,write阻塞

    注意:匿名管道只能用于具有关系的进程之间的通信(父子进程,兄弟进程)
*/

// 子进程发送数据给父进程,父进程读取到数据输出
#include <unistd.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main() {

    // 重点:在fork之前创建管道
    int pipefd[2];//传出参数
    int ret = pipe(pipefd);
    if(ret == -1) {
        perror("pipe");
        exit(0);
    }

    // 创建子进程
    pid_t pid = fork();
    if(pid > 0) {
        // 父进程:可实现先读再写
        printf("i am parent process, pid : %d\n", getpid());

        // 关闭写端
        //close(pipefd[1]);
        
        // 从管道的读取端读取数据
        char buf[1024] = {0};
        while(1) {
            int len = read(pipefd[0], buf, sizeof(buf));
            printf("parent recv : %s, pid : %d\n", buf, getpid());
            
            //向管道中写入数据
            char * str = "hello,i am parent";
            write(pipefd[1], str, strlen(str));
            sleep(1); 
        }

    } else if(pid == 0){
        // 子进程:可实现先写再读
        printf("i am child process, pid : %d\n", getpid());
        // 关闭读端
        //close(pipefd[0]);
        char buf[1024] = {0};
        while(1) {//while循环实现不断的发送数据
            // 向管道中写入数据
            char * str = "hello,i am child";
            write(pipefd[1], str, strlen(str));
            sleep(1);

            //父子进程交替接收数据
            int len = read(pipefd[0], buf, sizeof(buf));
            printf("child recv : %s, pid : %d\n", buf, getpid());
            bzero(buf, 1024);
        }
        
    }
    return 0;
}

查看管道缓冲大小函数

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

int main() {

    int pipefd[2];//传出参数

    int ret = pipe(pipefd);

    // 获取管道的大小:4KB 4096 可修改
    //第二个参数为宏值,表示获取管道的大小
    long size = fpathconf(pipefd[0], _PC_PIPE_BUF);

    printf("pipe size : %ld\n", size);

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值