管道

41 篇文章 0 订阅

无名管道pipe(有血缘关系进程间的通信,fork创建)(179)

  • 本质:1.内核创建的缓冲区(大小:4k),它是一个伪文件。
    2.由两个文件描述符int pfp[2]引用,一个表示读端pfp[0],一个表示写端pfp[1]。
    3.数据从写端流入管道,。从读端流出,它使用环形队列机制。
  • 进程之间是不能相互访问的,,要交换数据必须通过内核,在内核中开辟一块缓冲区,进程1把数据从用户空间拷贝到内核缓冲区,进程2再从内核缓冲区把数据取走,内核提供的这种机制称为:进程间通信(IPC,interprocess communication)。
  • 查看当前管道缓冲区的大小:ulimit -p
  • 局限性:1.数据自己读不能自己写
    2.不能反复读取数据
    3.管道采用半双工通信方式,数据只能在一个方向上流动
    4.只能在有公共祖先的进程间使用管道
  • 管道内核通过什么方法实现:内核缓冲区,环形队列
    在这里插入图片描述
管道进程的设计思路:

1.先利用pipe创建一个管道,此时返回两个文件描述符:pfp[0], pfp[1]。
2.为了创建有血缘关系的进程,利用fork创建子进程。
3.为了实现单向通信,▲父向子传数据:在子进程中关闭“写”(close(pfp[1])),在父进程中关闭“读”(close(pfp[0])),▲子向父传数据:在子进程中关闭“读”(close(pfp[0])),在父进程中关闭“写”(close(pfp[1]))。

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

成功:返回0,向pfp返回两个文件描述符,失败:返回-1.
使用管道完成进程间通信
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>

int main()
{
        int fd[2];
        int pipeline = pipe(fd);
        if(pipeline == -1)
        {
                perror("pipe error:");
                exit(1);
        }
        pid_t pid;
        pid = fork();
        if(pid == -1)
        {
                perror("fork error:");
                exit(1);
                }
        else if(pid == 0)
        {
                printf("I am child\n");
                close(fd[1]);
                char buf[1024];
                int r = read(fd[0],buf,sizeof(buf));
                if(r == 0)
                {
                        printf("the content is empty\n");
                }
                else
                {
                        write(STDOUT_FILENO,buf,r);
                }

        }
        else
        {
                printf("I am father\n");
                close(fd[0]);
                write(fd[1],"666666\n",strlen("666666\n"));
        }
        return 0;
}
使用文件进行进程间通信
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>

int main()
{
        int fp,pid;
        pid = fork();
        char *buf = "666666\n";
        if(pid == -1) 
        {
                perror("fork error:");
                exit(1);
        }
        else if(pid == 0)
        {
        printf("I am child\n");
                fp = open("aaa",O_RDWR);
                if(fp == -1)
                {
                        perror("open error:");
                        exit(1);
                }
                else
                {
                        int fd = read(fp,buf,sizeof(buf));
                        if(fd == 0)
                        {
                                printf("the content is empty\n");
                        }
                        else
                        {
                                write(STDOUT_FILENO,buf,fd);
                        }
                        }
        }
        else
        {
                printf("I am father\n");
                int fp = open("aaa",O_RDWR);
                if(fp == -1)
                {
                        perror("open error:");
                        exit(1);
                }
                else
                {
                        write(fp,buf,sizeof(buf));
        }
	}
return 0;
}

有名管道fifo(允许不相关进程间通信)

  • 创建fifo文件:
1.在命令行创建文件:
mkfifo -m  644  file.fifo

2.在c文件中创建
#include<sys/types.h>
#include<sys/stat.h>
int mkfifo(const char*pathname,mode_t mode);

成功:返回又名管道的文件描述符,失败:返回-1
现今常用的进程间通信方式有:

1.管道:使用最简单(pipe),无名管道,所以进行通信的两个进程一定要有共同的祖先进程。
2.信号:开销最小
3.共享映射区:无血缘关系(mmap)
4.本地套接字:最稳定

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值