温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

IPC-管道通信

发布时间:2020-07-08 17:55:45 来源:网络 阅读:499 作者:LHSTS 栏目:编程语言

管道(PIPE)


管道是一种最基本的IPC机制,由pipe函数在内核中开辟一块缓冲区(称为管道)用于通信,所以管道在用户程序看起来就像一个打开的文件,通过read(filedes[0]);或者write(filedes[1]);

int pipe(int filedes[2]);

参数:filedes参数传给用户程序两个文件描述符表。filedes[0]指向管道的读端,filedes[1]指向管道的
写端

返回值:成功返回0,失败返回-1

int fseek(FILE *stream, long offset, int fromwhere);

stream:将指向以fromwhere为基准

offset:偏移offset(指针偏移量)个字节的位置

返回值

    失败:(比如offset超过文件自身大小),则不改变stream指向的位置,函数返回一个非0值。

    成功:stream将指向fromwhere,偏移量offset个字节的位置。

父子进程通信的步骤:

1.父进程创建管道,开辟管道,得到两个文件描述符指向管道的两端IPC-管道通信
2.父进程fork创建出子进程,那么子进程也有两个文件描述符指向同一管道IPC-管道通信
3.父进程关闭fd[0],子进程关闭fd[1]。父进程可以往管道里写,子进程可以往管道里读,管道是环形队列实现的,数据从写端流入,读端流出,这就实现了进程间通信。IPC-管道通信

管道内部的实现机制:

IPC-管道通信

实际上管道没有单独的实现数据结构 ,他利用文件在Linux中,而是借助文件系统的file结构和VFS文件索引节点inode,通过将两个 file 结构指向同一个临时的VFS 索引节点,而这个 VFS 索引节点又指向一个物理页面而实现的。有两个file数据结构,但它们定义文件操作例程地址是不同的,其中一个是向管道中写入数据的例程地址,而另一个是从管道中读出数据的例程地址。这样,用户程序的系统调用仍然是通常的文件操作,而内核却利用这种抽象机制实现了管道这一特殊操作。

测试管道容量

测试原理:读端不读,写端一直写

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

int get_pipe_size(FILE* fd)
{
    fseek(fd,0,SEEK_SET);
    int start = ftell(fd);
    fseek(fd,0,SEEK_END);
    int end = ftell(fd);
    return end - start;
}

int main()
{
    int _pipe[2];
    int ret = pipe(_pipe);
    if(ret == -1)
    {
    //    printf("create pipe error ,error code is:%d\n",error);
        return 1;
    }

    pid_t id = fork();
    if(id <0)
    {
        printf("fork error");
        return 2;
    }
    else if(id == 0)  //child 关闭读端
    {
        close(_pipe[0]);
        int i =0;
        char* _msg = NULL;

        //the writer keep writing
        while(1)
        {
            _msg = "r";
            write(_pipe[1],_msg,strlen(_msg));  //一直写
            printf("%d\n",i);
            i++;
        }
        printf("write over...\n");
    }

    else
    {
        //father
        close(_pipe[1]);//关闭写端
        char _msg[100];
        int j =0;
        sleep(5);
        int status = 0;
        while(1)
        {
            status = 0;
            memset(_msg,'\0',sizeof(_msg));
            printf("%s:code id:%d\n",_msg,ret);

        }
        if(waitpid(id,&status,0)<0)
        {
            return 3;
        }
        printf("status:%d\n",(status)&0xff);
    }
    return 0;
}

测试结果:大约64k

IPC-管道通信



向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI