管道(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超过文件自身大小),则不改变stream指向的位置,函数返回一个非0值。
成功:stream将指向fromwhere,偏移量offset个字节的位置。
父子进程通信的步骤:
1.父进程创建管道,开辟管道,得到两个文件描述符指向管道的两端 | |
2.父进程fork创建出子进程,那么子进程也有两个文件描述符指向同一管道 | |
3.父进程关闭fd[0],子进程关闭fd[1]。父进程可以往管道里写,子进程可以往管道里读,管道是环形队列实现的,数据从写端流入,读端流出,这就实现了进程间通信。 |
管道内部的实现机制:
实际上管道没有单独的实现数据结构 ,他利用文件在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
时间: 2024-11-05 15:56:37