linux管道学习笔记

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

声明:本文档所有内容均为网上整理所得,不保证所有内容正确性.版权属作者本人所有。不用做任何商业用途,仅供广大网友学习交流之用,如有侵权,请联系本人删除,若发现文档中内容有错误或者有个人见解,欢迎指教与相互讨论.Email:.weiming999@。

管道

无名管道

管道包括无名管道和有名管道两种,前者在父子进程中流行,后者由于可以独立成为磁盘文件而存在,因为能够被无血缘关系的进程共享.

无名管道通常直接称为管道,它占用两个文件描述符,不能被非血缘关系的进程共享,一般应用于父子进程.

UNIX中一切皆为文件,管道也是一种文件,称为管道文件.当系统中创建一个管道时,它返回两个文件描述符:一个文件以只写打开,作为管道的输入端;另一个文件以只读打开,作为管道的输出端.

#include

int pipe(int fildes[2]);

函数pipe在内核中创建一个管道,并分配两个文件描述符标识管道的两端,这两个文件描述符存储与fildes[0]和fildes[1]中.一般约定fildes[0]描述管道和输出端,进程向此文件描述符中读取数据,fildes[1]描述管道的输入端,进程向此文件描述符写入数据.

fildes[0]:只读文件描述符.

fildes[1]:只写文件描述符.

Pipe调用成功返回0,否则返回-1.

单向管道流模型

管道的两端(输入端和输出端)被一个进程控制没有太大的意义,如果管道的两端分别控制在不同的进程中,这两个进程之间就能够进行通信.拥有管道输入端的进程,可以向管道发送数据,拥有管道输出端的进程,可以从管道中接受前一个进程发送来的消息.

1)从父进程流向子进程的管道

在父进程创建无名管道并产生子进程后,父子进程均拥有管道两端的访问权.此时关闭父进程的管道输出端,关闭子进程的管道输入端,就形成一个从父进程到子进程的管道流,数据由父进程写入,从子进程读出.

2)从子进程流向父进程的管道

在父进程中创建无名管道并产生子进程后,父子进程均拥有两端的访问权.此时关闭父进程的管道输入端,关闭子进程的管道输出端,就形成了一个从子进程到父进程的管道流.数据由子进程写入,从父进程读出.

#i n c l u d e

#i n c l u d e

#i n c l u d e

#i n c l u d e

i n t m a i n()

{

p i d_t p i d;

i n t f i l d e s[2];

c h a r b u f[256];

i n t i,j;

i f(p i p e(f i l d e s)<0)

{

p r i n t f("p i p e e r r o r\n");

r e t u r n-1;

}

i f((p i d=f o r k())<0)

{

p r i n t f("f o r k e r r o r!\n");

r e t u r n-1;

}

i f(0==p i d)

{

//子进程

c l o s e(f i l

d

e s[1]);

j=r e a d(f i l d e s[0],b u f,s i z e o f(b u f));

b u f[j]='\0';

p r i n t f("[c h i l d]l e n g t h=[%d]b u f=[%s]\n",j,b u f);

r e t u r n0;

}

//父进程

c l o s e(f i l

d

e s[0]);

w r i t e(f i l d e s[1],"H e l l o",s t r l e n("H e l l o"));

r e t u r n0;

}

在进程的通信中,我们无法判断每次通信中报文的字节数,即无法对数据流进行自动拆分,从而发生了子进程一次性读取父进程两次通信的报文,为了能正常拆分发送报文,常常采用以下几种方法:

a)固定长度.

b)显式长度.每条报文由长度域和数据域组成.长度域大小固定,储存了数据域长度.分为字

符串型和整形两种.数据域是传输的实际报文数据.接收进程先获取长度域的数据,转换成数据域的长度,再读取相应长度的信息即为数据域内容.

c)短连接.每当进程间需要通信时,创建一个通信线路,发生一条报文后立即废弃这调通线路.

这种方式在socket通信中很常用.

#i n c l u d e

#i n c l u d e

#i n c l u d e

#i n c l u d e

i n t m a i n()

{

p i d_t p i d;

i n t f i l d e s[2];

c h a r b u f[256];

i n t i,j;

i f(p i p e(f i l d e s)<0)

{

p r i n t f("p i p e e r r o r\n");

r e t u r n-1;

}

i f((p i d=f o r k())<0)

{

p r i n t f("f o r k e r r o r!\n");

r e t u r n-1;

}

i f(0==p i d)

{

//子进程

c l o s e(f i l

d

e s[1]);

j=r e a d(f i l d e s[0],b u f,5);

b u f[j]='\0';

p r i n t f("[c h i l d]l e n g t h=[%d]b u f=[%s]\n",j,b u f);

m e m s e t(b u f,0,s i z e o f(b u f));

j=r e a d(f i l d e s[0],b u f,5);

b u f[j]='\0';

p r i n t f("[c h i l d]l e n g t h=[%d]b u f=[%s]\n",j,b u f);