Linux管道的一些细节
Linux管道的一些细节
读管道:
1、进程从管道中读取数据时,进程被挂起直到数据被写进管道。(如果管道被两个进程共享,进程A关闭了读端,进程B读写都开启,B使用读端时,会一直等待B进程的写端的动作,而不会理会A的动作。)
2、当所有的写者关闭了管道的写数据端时,试图从管道中读取数据的调用返回0,意味着文件结束。
3、管道是一个队列。一个进程从管道中读取数据后,数据已经不存在了。如果两个进程都试图对同一个管道进行度操作,在一个读取一些之后,另一个进程读到的将是后面的内容。他们读到的数据必然是不完整的,除非两个进程用某种方式来协调它们对管道的访问。
写管道:
1、管道容纳的数据量是有限的,比磁盘文件差很多。如果进程想写入1000个字节,而管道只能容纳500个,那么写入调用只能等待,直到管道中再有500个字节。
2、当所有读者都关闭读数据端,则写操作失败。首先内核发送SIGPIPE消息给进程。若进程被终止,则无任何事情发生,否则write调用返回-1,并且将errno置为EPIPE。
3、POSIX标准规定内核不会拆分小于512字节的块。而Linux则保证管道中可以存在4096字节的连续缓存。如果两个进程向管道写数据,并且每一个进程都限制其消息不大于512字节,那么这些消息都不会被内核拆分。
这个示例程序,简单地展示了管道的使用:
- /*
- * @FileName: pipedemo.c
- * @Author: wzj
- * @Brief:
- *
- * @History:
- *
- *
- *
- * @Date: 2011年10月04日星期二18:55:23
- *
- */
- #include<stdio.h>
- #include<unistd.h>
- #include<stdlib.h>
- #include<string.h>
- #include<fcntl.h>
- int main()
- {
- int len, i, apipe[2];
- char buf[BUFSIZ];
- int tmfd;
- // tmfd = open("/etc/passwd", O_RDONLY);
- // dup2(tmfd, 2); // redirect output...
- // close(tmfd);
- // close(0); // can't get the input...
- // close(1); // can't output...
- close(2);
- /*get a pipe*/
- if(pipe(apipe) == -1)
- {
- perror("could not make pipe");
- exit(1);
- }
- printf("Got a pipe ! It is file descriptors: \
- { %d %d} BUFSIZE:%d\n", apipe[0], apipe[1], BUFSIZ);
- /*read from stdin, write into pipe, read from pipe, print*/
- while(fgets(buf, BUFSIZ, stdin))
- {
- len = strlen(buf);
- if(write(apipe[1], buf, len) != len)
- {
- perror("writing to pipe");
- break;
- }
- for(i=0; i<len ; i++)
- {
- buf[i] = 'X';
- }
- len = read(apipe[0], buf, BUFSIZ);
- if(len == -1)
- {
- perror("reading from pipe");
- break;
- }
- if(write(1, buf, len) != len)
- {
- perror("writing to stdout");
- break;
- }
- }
- return 0;
- }
|
评论暂时关闭