Chinaunix首页 | 论坛 | 博客
  • 博客访问: 326548
  • 博文数量: 31
  • 博客积分: 393
  • 博客等级: 一等列兵
  • 技术积分: 388
  • 用 户 组: 普通用户
  • 注册时间: 2012-08-26 10:23
文章分类

全部博文(31)

文章存档

2013年(16)

2012年(15)

分类: LINUX

2012-08-26 10:48:00

NOTE

Pipe数据结构

点击(此处)折叠或打开

  1. Struct inode{

  2. atomic_t        i_count;    //节点引用计数
  3. struct pipe_inode_info    *i_pipe;

  4. }

  5. struct pipe_inode_info {
  6.     wait_queue_head_t wait;    //等待队列
  7.     char *base;            //分配的共享页面地址
  8.     unsigned int start;        //起始位置的偏移量
  9.     unsigned int readers;        //读文件对象的个数filp, get_pipe_inode() 此项被置1,撤销了filp(filp->f_count=0 调用pipe_release),此项-1
  10.     unsigned int writers;        //写文件对象的个数filp,
  11.     unsigned int waiting_readers;    //阻塞的读文件对象个数
  12.     unsigned int waiting_writers;    //阻塞的写文件对象个数
  13.     unsigned int r_counter;        //fifo读打开的次数
  14.     unsigned int w_counter;    //fifo写打开的次数
  15. };


点击(此处)折叠或打开

  1. #define PIPE_SIZE        PAGE_SIZE
  2. #define PIPE_SEM(inode)        (&(inode).i_sem)
  3. #define PIPE_WAIT(inode)    (&(inode).i_pipe->wait)
  4. #define PIPE_BASE(inode)    ((inode).i_pipe->base)
  5. #define PIPE_START(inode)    ((inode).i_pipe->start)
  6. #define PIPE_LEN(inode)        ((inode).i_size)
  7. #define PIPE_READERS(inode)    ((inode).i_pipe->readers)
  8. #define PIPE_WRITERS(inode)    ((inode).i_pipe->writers)
  9. #define PIPE_WAITING_READERS(inode)    ((inode).i_pipe->waiting_readers)
  10. #define PIPE_WAITING_WRITERS(inode)    ((inode).i_pipe->waiting_writers)
  11. #define PIPE_RCOUNTER(inode)    ((inode).i_pipe->r_counter)
  12. #define PIPE_WCOUNTER(inode)    ((inode).i_pipe->w_counter)
  13. #define PIPE_EMPTY(inode)    (PIPE_LEN(inode) == 0)
  14. #define PIPE_FULL(inode)    (PIPE_LEN(inode) == PIPE_SIZE)
  15. #define PIPE_FREE(inode)    (PIPE_SIZE - PIPE_LEN(inode))
  16. #define PIPE_END(inode)    ((PIPE_START(inode) + PIPE_LEN(inode)) & (PIPE_SIZE-1))
  17. #define PIPE_MAX_RCHUNK(inode)    (PIPE_SIZE - PIPE_START(inode))
  18. #define PIPE_MAX_WCHUNK(inode)    (PIPE_SIZE - PIPE_END(inode))


二 .管道读取的情景分析:
1如果管道为空
  管道无生产者(写端被关闭了)ret:0
  非阻塞(O_NONBLOCK)的方式度管道(默认为阻塞),ret:0
  阻塞,做如下判断
  (1)进程自我阻塞直到被唤起
  (2)管道非空,跳到2
  (3)无写者,ret : 0
  (4)到这了,说明进程的唤起和本管道没有太大的关系,继续到(1)进入睡眠直到被唤起
2管道非空
  读管道,管道其实是个页面缓存,他的读法下面介绍
  如果:管道的数据(size)不够读取(count)
  在阻塞及有生产者的情况下,唤起生产者,跳到1.  。
  否则ret:read

Ps:得出的一般结论,如果在阻塞的情况下读取管道的返回值ret小于预期要读取的字节数count,可判断为管道没有生产者了(写端被关闭)

三. 读取非空的管道
Count:为预期要在管道读的字节数
PIPE_LEN:管道中的字节数
PIPE_BASE:缓冲页面起始地址
PIPE_START:内容的偏移量
PIPE_END(inode) ((PIPE_START(inode) + PIPE_LEN(inode)) & (PIPE_SIZE-1)) 内容的结束位置
PIPE_MAX_RCHUNK(inode) (PIPE_SIZE - PIPE_START(inode)) 内容开始到页面低的容量

缓冲页面的各个参数如下图所示:
 
页面的使用时循环的
 

读取管道数据的代码如下:

点击(此处)折叠或打开

  1. while (count > 0 && (size = PIPE_LEN(*inode))) {
  2.     char *pipebuf = PIPE_BASE(*inode) + PIPE_START(*inode);    //数据的起始位置
  3.     ssize_t chars = PIPE_MAX_RCHUNK(*inode);            //start到一面尾的长度

  4.     if (chars > count)
  5.         chars = count;
  6.     if (chars > size)
  7.         chars = size;
  8. //chars取 count,size, PIPE_MAX_RCHUNK的最小值
  9.     if (copy_to_user(buf, pipebuf, chars))    //将pipebuf中的chars个字节拷贝到用户空间的buf
  10.         goto out;

  11.     read += chars;                //已经读取了read个字节
  12.     PIPE_START(*inode) += chars;        //移动start推移:度过的数据就丢弃
  13.     PIPE_START(*inode) &= (PIPE_SIZE - 1); // start%=pagesize
  14.     PIPE_LEN(*inode) -= chars;        //管道中的数据量减chars
  15.     count -= chars;                //与读取的数据量减chars
  16.     buf += chars;                //用户空间缓冲的填充指针
  17. }

情况1:PIPE_MAX_RCHUNK>PIPE_LEN>count
                       
       Chars=count 

 读取后的pipe
情况2:PIPE_MAX_RCHUNK> count> PIPE_LEN
 
Chars=pipe_len,读取后进程进入阻塞(非阻塞返回chars),并且PIPE_START=PIPE_END=0
情况3 :PIPE_LEN > PIPE_MAX_RCHUNK> count 
 
Chars=count,和情况一是一个效果。

情况4: PIPE_LEN >count>PIPE_MAX_RCHUNK
 

chars= PIPE_MAX_RCHUNK   
         chars=count
接着便是情况1的读取方式了。
情况5:count>PIPE_LEN > PIPE_MAX_RCHUNK
                                                    
1.chars= PIPE_MAX_RCHUNK         


.chars=PIPE_SIZE ,接着便是情况2的读取方式了
阅读(2018) | 评论(0) | 转发(0) |
0

上一篇:没有了

下一篇:JavaScript 日期时间的显示(时钟)

给主人留下些什么吧!~~