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字节,那么这些消息都不会被内核拆分。

这个示例程序,简单地展示了管道的使用:

  1. /* 
  2.  * @FileName: pipedemo.c 
  3.  * @Author: wzj 
  4.  * @Brief:  
  5.  *   
  6.  * @History:  
  7.  *  
  8.  *  
  9.  *  
  10.  * @Date: 2011年10月04日星期二18:55:23 
  11.  *  
  12.  */   
  13. #include<stdio.h>   
  14. #include<unistd.h>   
  15. #include<stdlib.h>   
  16. #include<string.h>   
  17. #include<fcntl.h>   
  18.   
  19. int main()  
  20. {  
  21.     int     len, i, apipe[2];  
  22.     char    buf[BUFSIZ];  
  23.     int     tmfd;  
  24.   
  25. //  tmfd = open("/etc/passwd", O_RDONLY);   
  26. //  dup2(tmfd, 2); // redirect output...   
  27. //  close(tmfd);   
  28. //  close(0);     // can't get the input...   
  29. //  close(1);   // can't output...   
  30.   
  31.     close(2);  
  32.     /*get a pipe*/  
  33.     if(pipe(apipe) == -1)  
  34.     {  
  35.         perror("could not make pipe");  
  36.         exit(1);  
  37.     }  
  38.   
  39.     printf("Got a pipe ! It is file descriptors: \  
  40.             { %d %d} BUFSIZE:%d\n", apipe[0], apipe[1], BUFSIZ);  
  41.       
  42.     /*read from stdin, write into pipe, read from pipe, print*/  
  43.     while(fgets(buf, BUFSIZ, stdin))  
  44.     {  
  45.         len = strlen(buf);  
  46.         if(write(apipe[1], buf, len) != len)  
  47.         {  
  48.             perror("writing to pipe");  
  49.             break;  
  50.         }  
  51.   
  52.         for(i=0; i<len ; i++)  
  53.         {  
  54.             buf[i] = 'X';  
  55.         }  
  56.         len = read(apipe[0], buf, BUFSIZ);  
  57.         if(len == -1)  
  58.         {  
  59.             perror("reading from pipe");  
  60.             break;  
  61.         }  
  62.   
  63.         if(write(1, buf, len) != len)  
  64.         {  
  65.             perror("writing to stdout");  
  66.             break;  
  67.         }  
  68.     }  
  69.   
  70.     return 0;  
  71. }  
  • 1
  • 2
  • 下一页

相关内容