管道操作分为两部分,一部分是创建管道,另一部分是管道的读写操作。代码如下:
#include <stdio.h>
#include <unistd.h>
int main()
{
int n,fd[2];
pid_t pid;
int i,j;
char str1[]="ABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDE
ABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDE
ABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDE
ABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDE
ABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDE
ABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDE
ABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDE
ABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDE
ABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDE
ABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDE
ABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDE
ABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDEABCDE";
char str2[512];
if(pipe(fd)<0)
{
printf("pipe error\n");
return -1;
}
if((pid = fork())<0)
{
printf("fork error\n");
return -1;
}else if(pid > 0)
{
close(fd[0]);
for(i=0;i<10000;i++)
write(fd[1],str1,strlen(str1));
}
else
{
close(fd[1]);
for(j=0;j<20000;j++)
read(fd[0],str2,strlen(str2));
}
} 父进程把str1中的数据写入管道,子进程从管道中读出数据,其中str1中字符长度为1024字节,即1KB。
pipe会映射到sys_pipe执行,代码路径:fs/pipe.c
int sys_pipe(unsigned long * fildes)
{
struct m_inode * inode;
struct file * f[2];
int fd[2];
int i,j;
j=0;
for(i=0;j<2 && i<NR_FILE;i++)//准备在file_table[64]中申请两个空闲项
if (!file_table[i].f_count)//找到空闲项
(f[j++]=i+file_table)->f_count++;//每项引用计数为1
if (j==1)
f[0]->f_count=0;
if (j<2)
return -1;
j=0;
for(i=0;j<2 && i<NR_OPEN;i++)//准备在*filp[20]中申请两个空闲项
if (!current->filp[i]) {//找到空闲项
current->filp[ fd[j]=i ] = f[j];//分别与file_table[64]中申请的两个空闲项挂接
j++;
}
if (j==1)
current->filp[fd[0]]=NULL;
if (j<2) {
f[0]->f_count=f[1]->f_count=0;
return -1;
}
if (!(inode=get_pipe_inode())) {//创建管道文件i节点
current->filp[fd[0]] =
current->filp[fd[1]] = NULL;
f[0]->f_count = f[1]->f_count = 0;
return -1;
}
f[0]->f_inode = f[1]->f_inode = inode;//i节点和表项挂接
f[0]->f_pos = f[1]->f_pos = 0;//文件指针归0
f[0]->f_mode = 1; /* read */ //设置为读模式
f[1]->f_mode = 2; /* write */ //设置为写模式
put_fs_long(fd[0],0+fildes); //将读管道文件句柄返回到用户空间(用户空间变量fd[0])
put_fs_long(fd[1],1+fildes); //将写管道文件句柄返回到用户空间(用户空间变量fd[1])
return 0;
} 创建管道文件i节点,代码如下:
代码路径:fs/inode.c
struct m_inode * get_pipe_inode(void)
{
struct m_inode * inode;
if (!(inode = get_empty_inode()))//申请空闲inode节点
return NULL;
if (!(inode->i_size=get_free_page())) {//承载的不再是文件大小,而是内存页面的起始地址
inode->i_count = 0;
return NULL;
}
inode->i_count = 2; /* sum of readers/writers */ //引用计数设置为2
PIPE_HEAD(*inode) = PIPE_TAIL(*inode) = 0;//PIPE_HEAD为写管道指针,PIPE_TAIL为读管道指针,都设置为0
inode->i_pipe = 1;//设置管道文件属性
return inode;
} 代码路径:include/linux/fs.h
#define PIPE_HEAD(inode) ((inode).i_zone[0]) #define PIPE_TAIL(inode) ((inode).i_zone[1]) #define PIPE_SIZE(inode) ((PIPE_HEAD(inode)-PIPE_TAIL(inode))&(PAGE_SIZE-1))
Linux内核设计的艺术-进程间通信,布布扣,bubuko.com
原文:http://blog.csdn.net/jltxgcy/article/details/21931927