Chinaunix首页 | 论坛 | 博客
  • 博客访问: 581052
  • 博文数量: 126
  • 博客积分: 4379
  • 博客等级: 上校
  • 技术积分: 2110
  • 用 户 组: 普通用户
  • 注册时间: 2006-03-06 22:35
文章分类

全部博文(126)

文章存档

2012年(5)

2011年(3)

2010年(2)

2009年(116)

分类: LINUX

2009-07-14 23:45:49

 

 

 

管道或FIFOopenreadwrite以及相关的阻塞与非阻塞是这一部分的难点,这些概念不是很难,但是揉在一起就让人感觉理不清头绪, 仔细研究了这一部分很多遍,总算有点头绪。借用《UNP》上的表:

 

当前操作

PipeFIFO

现有操作

返回

阻塞

O_NONBLOCK

Open

FIFO

O_RDONLY

 

 

Open(FIFO, O_WRONLY)

成功

成功

Open(FIFO,

O_RDONLY)或无open

阻塞到

Open(FIFO, O_WRONLY)

成功

Open

(FIFO

O_WRONLY)

 

 

OpenFIFO

O_RDONLY

成功

成功

Open(FIFO, O_WRONLY)

open

 

阻塞到

OpenFIFOO_RDONLY

ENOXIO

从空pipe或空FIFO

Read

 

管道或FIFO打开来写

阻塞到pipeFIFO中有数据

PipeFIFO不再为写打开

EAGAIN

管道或FIFO不是打开来写

返回0EOF

返回0EOF

往管道或FIFO write

 

 

管道或FIFO打开来读

 

 

管道或FIFO不是打开来读

SIGPIPE

SIGPIPE

 

1open Open(FIFO, O_WRONLY)Open(FIFO, O_RDONLY)要成对出现,否则就会阻塞对于设置了O_NONBLOCK标志的,Open(FIFO, O_WRONLY)之前必须有Open(FIFO, O_RDONLY),否则会返回ENOXIO 这一点都比较好理解。

2read and write 这一点比较乱,还是用代码说话比较好,下面是代码片段。

 

       if ( (childpid = Fork()) == 0) {            /* child */

              readfd = Open(FIFO1, O_RDONLY, 0);

              writefd = Open(FIFO2, O_WRONLY, 0);

             

//4

       Close(readfd);                                    //管道或FIFO不是打开来读

//

                                                                             //// 从空pipe或空FIFORead

              if ( (n = Read(readfd, buff, MAXLINE)) == 0)                  //2)返回EOF

              err_quit("end-of-file while reading pathname");           //1)阻塞

             

              exit(0);

       }

              /* 4parent */

       writefd = Open(FIFO1, O_WRONLY, 0);

       readfd = Open(FIFO2, O_RDONLY, 0);

      

       Fgets(buff, MAXLINE, stdin);

      

// (2)

       Close(writefd);                                                               //管道或FIFO不是打开来写

//

//(1)                                                                                     //管道或FIFO打开来写

       Len = 0;

//

       Write(writefd, buff, len);                                                 //4)产生SIGPIPE

 

标记(1)、(2)、(3)、(4)是添加的代码实现上面表格中标记的功能。第(3)中情况,要注意写不能溢出缓冲区就可以了,否则情况就难以预知了。

 

不知道这样能不能看明白,说明一下:

1FIFO打开来写的,但写入0字节,模拟使FIFO为空,子进程Read就会阻塞。

2closewritefd)使FIFO不再为写打开, 子进程Read会返回EOF

4)子进程closereadfd)使FIFO不再打开来读, 父进程Write会产生SIGPIPE

 

阅读(2096) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~