匿名管道

1.进程通信的目的

    (1) 数据传输: 一个进程需要将它的数据传输给另一个进程
    (2) 资源共享: 多个进程之间共享同样的资源
    (3) 通知事件: 一个进程需要向另一个或一组进程发送消息, 通知它们发生了什么事情

2.管道

    管道是一种进程之间通信的一种方式, 我们把从一个进程连接到另一个进程的数据流叫做管道

3.匿名管道

    (1) 匿名管道的创建

int pipe(int fd[2]);
fd是一个文件描述符数组, fd[0] 代表读端, fd[1] 代表写端
返回值:成功过时返回0, 失败时返回错误代码
4.代码演示
//clientPipe.c
#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<fcntl.h>
#include<stdlib.h>

int main()
{
    int wfd = open("mypipe", O_WRONLY);
    if(wfd == -1)//dakashibai
    {
        perror("open");
        exit(1);
    }

    char buf[1024];
    buf[0] = 0;
    ssize_t s;
    while(1)
    {
        printf("Please Enter#");
        fflush(stdout);
        s = read(0, buf, sizeof(buf));
        if(s > 0)//成功读取
        {
            buf[s] = 0;
            write(wfd, buf, s);
        }

        else if(s <= 0)//读取失败
        {
            perror("read");
            exit(1);
        }
    }
}

//serverPipe.c
#include<stdio.h>
#include<unistd.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<stdlib.h>
#include<sys/types.h>

int main()
{
    int fifo = mkfifo("mypipe", 0644);
    if(fifo == -1)//管道创建失败
    {
        perror("mkfifo");
        exit(1);
    }

    //打开管道
    int rfd = open("mypipe", O_RDONLY);
    if(rfd == -1)//打开失败
    {
        perror("open");
        exit(1);
    }

    //读管道数据
    char buf[1024];
    ssize_t s;
    while(1)
    {
        buf[0] = 0;
        printf("Please wait ... \n");
        s = read(rfd, buf, sizeof(buf) -1);

        if(s > 0)//读到数据
        {
            buf[s] = 0;
            printf("client say# %s", buf);
        }

        else if(s == 0)//读完
        {
            printf("client quit, exit now\n");
            exit(0);
        }

        else//读取失败
        {
            perror("read");
            exit(1);
        }
    }

    close(rfd);
    return 0;
}

             这里写图片描述

5.站在文件描述符角度理解

这里写图片描述
这里写图片描述
    父进程先创建管道, 创建完管道,同时父进程打打开对应的读端和写端,接着父进程创建子进程, 由于子进程会继承父进程的特性, 因此子进程也会打开和父进程一样的读端和写端, 此时父子进程就看到了一份公共资源, 紧接着父进程将读端关闭, 子进程将写端关闭, 于是便可以父进程进行对数据的写,子进程只管从管道中读数据即可,于此父子进程合作完成读写工作.

6.管道读写规则

     (1) 当管道读端关闭, 写端还在继续写的时候此时操作系统会给写端发送一个 SIGPIPE 的信号,从而使得写端退出
     (2) 如果写端对应的描述符关闭, 读端则会正常退出.
     (3) 管道具有上限,当写到 PIPE_BUF 时, Linux 将不再保证其写入的原子性.
     (4) 注意匿名管道对应的两个进程之间一定是由血缘关系的

7. 管道特点

     (1) 管道具有单向性
     (2) 有血缘关系的进程之间才能进行通信(匿名管道)
     (3) 管道必须满足同步互斥关系(管道没有数据时,读端进程将会不读,阻塞等待, 当管道已经满的时候就不能对管道进行写了)
     (4) 管道的生命周期随进程
     (5) 管道提供字节流服务(从管道中一次读多少由操作系统决定, 即一次读写多少不确定)

8. 相关的几个概念

     (1) 数据不一致: 一个进程的读写影响到另外一个进程的读写
     (2) 临界资源: 两个进程看到的一份公共资源,并且一次只允许一个进程使用
     (3) 临界区: 进程访问临界资源的那段代码就叫做临界资源
     (4) 互斥: 各进程有时需要共享资源, 而且有些资源需要互斥访问, 因此进程之间竞争使用这些资源, 进程之间的这种关系叫做互斥
     (5) 进程访问资源的原子性: 进程在操作某些资源时要不做完, 要不不做, 中间不会收到如何其他进程的干扰.
     (6) 同步: 进程之间以一种比较安全的顺序访问资源, 这种安全机制就叫做同步
     (7) 管道自带同步互斥机制, 当管道中没有数据时父进程会等待子进程的退出

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值