Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1743058
  • 博文数量: 297
  • 博客积分: 285
  • 博客等级: 二等列兵
  • 技术积分: 3006
  • 用 户 组: 普通用户
  • 注册时间: 2010-03-06 22:04
个人简介

Linuxer, ex IBMer. GNU https://hmchzb19.github.io/

文章分类

全部博文(297)

文章存档

2020年(11)

2019年(15)

2018年(43)

2017年(79)

2016年(79)

2015年(58)

2014年(1)

2013年(8)

2012年(3)

分类: LINUX

2016-01-27 13:56:11

第一个例子:fork() 出子进程,父进程关闭pipe读,使用write 向管道写入,子进程关闭pipe写,然后从管道读取。

点击(此处)折叠或打开

  1. #include <apue.h>

  2. #define READ_FD 0
  3. #define WRITE_FD 1

  4. int main(int argc, char *argv[])
  5. {
  6.     int i;
  7.     int bytesread;
  8.     int fd[2];
  9.     char message[BUFSIZ];

  10.     // check proper usage
  11.     if(argc < 2){
  12.         fprintf(stderr, "Usage: %s message \n",argv[0]);
  13.         exit(1);
  14.         }

  15.     // try to create pipe
  16.     if( -1 == pipe(fd)){
  17.         perror("pipe call");
  18.         exit(2);
  19.         }

  20.     //create child process
  21.     switch(fork()){
  22.         case -1:
  23.             //fork failed
  24.             perror("fork failed");
  25.             exit(3);
  26.         
  27.         case 0:
  28.             //child code
  29.             //close write end, otherwise child will never terminate
  30.             close(fd[WRITE_FD]);
  31.             //loop while not end of ile or not a read error
  32.             while((bytesread = read(fd[READ_FD],message, BUFSIZ))!= 0)
  33.                 if(bytesread >0 ){ //more data
  34.                     message[bytesread]='\0';
  35.                     printf("Child received the word: '%s'\n",message);
  36.                     fflush(stdout);
  37.                     }
  38.                 else{//read error
  39.                     perror("read() ");
  40.                     exit(4);
  41.                     }
  42.             exit(0);
  43.         
  44.         default: //parent code
  45.             close(fd[READ_FD]); //close read end,since parent is writing
  46.             for(i=1; i< argc; i++)
  47.                 //send each word separately
  48.                 if(write(fd[WRITE_FD],argv[i],strlen(argv[i]))!=-1)
  49.                 {
  50.                     printf("Parent sent the word: '%s' \n",argv[i]);
  51.                     fflush(stdout);
  52.                     }
  53.                 else{
  54.                     perror("write()");
  55.                     exit(5);
  56.                     }
  57.                 close(fd[WRITE_FD]);
  58.             
  59.             //wait for child so it does not remain a zombie
  60.             //do not care about it's status,so pass a NULL pointer
  61.             if( wait(NULL)==-1){
  62.                 perror("Wait failed");
  63.                 exit(2);
  64.                 }
  65.             }
  66.             exit(0);
  67.             }
第二个例子:这个例子纯粹是为了说明write 写入的内容小于PIPE_BUF 的时候,操作是原子性的。
fork出两个进程,一个进程写入X,另外一个进程写入y,父进程向两个子进程发送SIGUSR1的信号,子进程开始写入,父进程读取管道内容,然后写入pd2_output。

点击(此处)折叠或打开

  1. #include <apue.h>
  2. #include <sys/wait.h>
  3. #include <unistd.h>
  4. #include <limits.h>
  5. #include <fcntl.h>


  6. #define READ_FD 0
  7. #define WRITE_FD 1
  8. #define RD_CHUNK 10
  9. #define ATOMIC

  10. #ifndef PIPE_BUF
  11.     #define PIPE_BUF _POSIX_PIPE_BUF
  12. #endif

  13. void do_nothing(int signo)
  14. {
  15.     return ;
  16. }

  17. int main(int argc, char *argv[])
  18. {
  19.     int i,repeat;
  20.     int bytesread;
  21.     int mssglen;
  22.     pid_t child1, child2;
  23.     int fd[2];
  24.     int outfd;

  25.     char message[RD_CHUNK + 1];
  26.     char *Child1_Chunk, *Child2_Chunk;
  27.     long Chunk_Size;

  28.     static struct sigaction sigact;

  29.     sigact.sa_handler=do_nothing;
  30.     sigfillset(&(sigact.sa_mask));
  31.     sigaction(SIGUSR1, &sigact, NULL);

  32.     //check argc
  33.     if( argc < 2){
  34.         fprintf(stderr,"Usage: %s size \n",argv[0]);
  35.         exit(1);
  36.     }

  37.     //try to create pipe
  38.     if(-1 == pipe(fd)){
  39.         perror("pipe call");
  40.         exit(2);
  41.     }

  42.     repeat=atoi(argv[1]);

  43. #ifdef ATOMIC
  44.     Chunk_Size = PIPE_BUF;
  45. #else
  46.     Chunk_Size = PIPE_BUF + 200;
  47. #endif
  48.     printf("Chunk size =%ld\n",Chunk_Size);
  49.     printf("Value of PIPE_BUF is %ld\n",PIPE_BUF);
  50.     Child1_Chunk=calloc(Chunk_Size,sizeof(char));
  51.     Child2_Chunk=calloc(Chunk_Size,sizeof(char));
  52.     if((NULL == Child1_Chunk) ||(NULL == Child2_Chunk)){
  53.         perror("calloc");
  54.         exit(2);
  55.     }

  56.     //create the string that child1 writes
  57.     Child1_Chunk[0] = '\0'; //just to be safe
  58.     for(i=0; i < Chunk_Size -2; i++)
  59.         strcat(Child1_Chunk,"X");
  60.     strcat(Child1_Chunk,"\n");

  61.     //create the string that child2 writes
  62.     Child2_Chunk[0]='\0'; //just to be safe
  63.     for(i=0;i<Chunk_Size -2;i++)
  64.         strcat(Child2_Chunk,"y");
  65.     strcat(Child2_Chunk,"\n");

  66.     //create first child process
  67.     switch(child1 = fork()){
  68.         case -1: //fork failed -- exit
  69.             perror("fork()");
  70.             exit(3);

  71.         case 0: //child1 code
  72.             mssglen=strlen(Child1_Chunk);
  73.             pause();
  74.             //sleep(5);
  75.             for(i=0;i<repeat;i++){
  76.                 if(write(fd[WRITE_FD],Child1_Chunk,mssglen)!= mssglen){
  77.                     perror("write");
  78.                     exit(4);
  79.                 }
  80.             }
  81.             close(fd[WRITE_FD]);
  82.             exit(0);

  83.         default: //parent creates second child process
  84.             switch(child2 = fork()){
  85.                 case -1: //fork failed --exit
  86.                     perror("fork()");
  87.                     exit(5);

  88.                 case 0: //child2 code
  89.                     mssglen=strlen(Child2_Chunk);
  90.                     pause();
  91.                     for(i=0;i<repeat;i++){
  92.                         if(write(fd[WRITE_FD],Child2_Chunk,mssglen)!= mssglen){
  93.                             perror("write");
  94.                             exit(6);
  95.                         }
  96.                     }
  97.                     close(fd[WRITE_FD]);
  98.                     exit(0);

  99.                 default: //parent code
  100.                     outfd=open("pd2_output",O_WRONLY|O_CREAT|O_TRUNC,0644);
  101.                     if(-1==outfd){
  102.                         perror("open");
  103.                         exit(7);
  104.                     }
  105.                     close(fd[WRITE_FD]);
  106.                     kill(child2,SIGUSR1);
  107.                     kill(child1,SIGUSR1);
  108.                     while((bytesread = read(fd[READ_FD],message,RD_CHUNK))!=0)
  109.                         if(bytesread >0 ){ //more data
  110.                             write(outfd,message,bytesread);
  111.                         }
  112.                         else{
  113.                             perror("read() ");
  114.                             exit(8);
  115.                         }
  116.                     close(outfd);
  117.                     //collect zombies
  118.                     for(i=1;i<=2;i++)
  119.                         if(wait(NULL)==-1){
  120.                             perror("wait failed");
  121.                             exit(9);
  122.                         }
  123.                         close(fd[READ_FD]);
  124.                         free(Child1_Chunk);
  125.                         free(Child2_Chunk);
  126.                     }
  127.                     exit(0);
  128.             }
  129.     }
3. 最后一个例子:管道的最大容量居然是65536,如果管道内空间少于4096,则不能写入。

点击(此处)折叠或打开

  1. #include <apue.h>
  2. #include <limits.h>
  3. #include <unistd.h>

  4. int count = 0;
  5. sig_atomic_t full =0;

  6. /* The SIGALRM handler, this sets the full flag to indicate that the
  7. write call blocked, and it prints the number of characters written
  8. to the pipe so far */

  9. void on_alarm(int signo)
  10. {
  11.     printf("\n Write() blocked with %d chars in the pipe.\n",count);
  12.     full=1;
  13.     }


  14. int main(int argc, char *argv[])
  15. {
  16.     int fd[2];
  17.     int pipe_size;
  18.     int bytesread;
  19.     int amount_to_remove;

  20.     char buffer[PIPE_BUF];
  21.     char c='x';
  22.     static struct sigaction sigact;

  23.     sigact.sa_handler=on_alarm;
  24.     sigfillset(&(sigact.sa_mask));
  25.     sigaction(SIGALRM,&sigact,NULL);

  26.     if( -1 == pipe(fd)){
  27.         perror("pipe failed");
  28.         exit(1);
  29.         }

  30.     /* Check whether the _PC_PIPE_BUF constant returns the pipe capacity
  31.     or the atomic write size */
  32.     pipe_size = fpathconf(fd[0],_PC_PIPE_BUF);

  33.     while (1){
  34.         /* set an alarm long enough that if write fails it will fail
  35.         within this amount of time. 8 seconds is long enough */
  36.         alarm(4);
  37.         write(fd[1],&c,1);
  38.         //unset the alarm
  39.         alarm(0);

  40.         //Did alarm expire? if so, write failed and we stop the loop
  41.         if(full)
  42.             break;

  43.         //report how many chars written so far
  44.         if(( ++count %1024)==0)
  45.             printf("%d chars in pipe \n",count);
  46.             }

  47.     printf("The maximum number of bytes that the pipe stored is %d.\n",count);
  48.     printf("The value returned by fpathconf (fd,_PC_PIPE_BUF) is %d.\n\n",pipe_size);

  49.     printf("Now we remove characters from the pipe and demonstrate that "
  50.             "we can not \n"
  51.             "write into the pipe unless it has %d (PIPE_BUF) free bytes.\n",PIPE_BUF);

  52.     amount_to_remove= PIPE_BUF -1;

  53.     printf("First we remove %d characters (PIPE_BUF -1) and try to write into the pipe.\n",amount_to_remove);
  54.     full=0;
  55.     bytesread=read(fd[0],&buffer,amount_to_remove);
  56.     if(bytesread < 0){
  57.         perror("error reading pipe");
  58.         exit(1);
  59.         }

  60.     count = count - bytesread;
  61.     alarm(4);
  62.     write(fd[1],&c, 1);
  63.     //unset the alarm
  64.     alarm(0);
  65.     if(full)
  66.         printf("We could not write into the pipe.\n");
  67.     else
  68.         printf("We successfully wrote into the pipe.\n");

  69.     amount_to_remove =PIPE_BUF - amount_to_remove;
  70.     full=0;

  71.     printf("\n Now we remove one more character and try to write into the pipe.\n");

  72.     bytesread=read(fd[0],&buffer, amount_to_remove);
  73.     if(bytesread < 0){
  74.         perror("error reading pipe");
  75.         exit(1);
  76.         }

  77.     count = count - bytesread;
  78.     alarm(4);
  79.     
  80.     write(fd[1],&c, 1);
  81.     //unset the alarm
  82.     alarm(0);
  83.     if(full)
  84.         printf("We could not write into the pipe.\n");
  85.     else
  86.         printf("We successfully wrote into the pipe.\n");

  87.     return 0;
  88.     }

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