Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2150537
  • 博文数量: 438
  • 博客积分: 3871
  • 博客等级: 中校
  • 技术积分: 6075
  • 用 户 组: 普通用户
  • 注册时间: 2011-09-10 00:11
个人简介

邮箱: wangcong02345@163.com

文章分类

全部博文(438)

文章存档

2017年(15)

2016年(119)

2015年(91)

2014年(62)

2013年(56)

2012年(79)

2011年(16)

分类: LINUX

2016-02-15 16:16:51

1. 进程间通信之pipe

2.单向通道
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <string.h>
  5. //child--->pipe-->parent
  6. int main ( int argc, char *argv[] )
  7. {
  8.     int fd[2];
  9.     pid_t pid;
  10.     char buf[1024];
  11.     if(pipe(fd) < 0)
  12.     {
  13.         perror("pipe error\n");
  14.         return -1;
  15.     }

  16.     printf("next fork\n");
  17.     pid = fork();
  18.     if(pid<0)
  19.     {
  20.         perror("fork error\n");
  21.         return -1;
  22.     } else if(pid==0) //child
  23.     {
  24.         close(fd[0]); //close read
  25.         //write data to parent
  26.         write(fd[1], "hello,world\n", strlen("hello,world\n")+1);
  27.     } else if(pid > 0) //parent
  28.     {
  29.         close(fd[1]); //close write
  30.         //read data frome child
  31.         read(fd[0], buf, sizeof(buf));
  32.         printf("recv_buf=%s", buf);
  33.     }
  34.     return EXIT_SUCCESS;
  35. }
2.1 模拟僵死的子进程
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <string.h>
  5. #include <signal.h>

  6. //typedef void (*sighandler_t)(int);
  7. //sighandler_t signal(int signum, sighandler_t handler);

  8. //child--->pipe-->parent
  9. pid_t child_pid;

  10. void sig_child_process(int signo)
  11. {
  12.     waitpid(child_pid, NULL, 0);
  13. }

  14. int main ( int argc, char *argv[] )
  15. {
  16.     int fd[2];
  17.     char buf[1024];
  18.     //signal(SIGCHLD, sig_child_process);   //不打开这个,即不等侍child进程的pid,则子进程会出现死锁
  19.     if(pipe(fd) < 0)
  20.     {
  21.         perror("pipe error\n");
  22.         return -1;
  23.     }

  24.     printf("next fork\n");
  25.     child_pid = fork();
  26.     if(child_pid<0)
  27.     {
  28.         perror("fork error\n");
  29.         return -1;
  30.     }else if(child_pid==0) //child
  31.     {
  32.         close(fd[0]); //close read
  33.         sleep(3);
  34.         //write data to parent
  35.         write(fd[1], "hello,world\n", strlen("hello,world\n")+1);  //write完子进程就退出了,但是父进程没有等侍子进程的退出信号
  36.     }else if(child_pid > 0) //parent                               //此时子进程处于僵死状态
  37.     {
  38.         close(fd[1]); //close write
  39.         //read data frome child
  40.         read(fd[0], buf, sizeof(buf));
  41.         printf("recv_buf=%s", buf);
  42.         sleep(5);
  43.     }
  44.     return EXIT_SUCCESS;
  45. }

3.双向通道
流程如下:
cwrite-->pread-->pwrite-->cread-->cexit
                            同时pwait    ---->    pwait_over
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <string.h>
  5. //child--->pipe-->parent
  6. //child<---pipe<--parent
  7. void parent_process(int readfd, int writefd);
  8. void child_process(int readfd, int writefd);

  9. int main ( int argc, char *argv[] )
  10. {
  11.     int pipe1[2];
  12.     int pipe2[2];
  13.     pid_t pid;
  14.     char buf[1024];
  15.     if(pipe(pipe1) < 0)
  16.     {
  17.         perror("pipe1 error\n");
  18.         return -1;
  19.     }
  20.     if(pipe(pipe2) < 0)
  21.     {
  22.         perror("pipe2 error\n");
  23.         return -1;
  24.     }

  25.     printf("next fork\n");
  26.     if( (pid = fork()) < 0)
  27.     {
  28.         perror("fork error\n");
  29.         return -1;
  30.     } else if(pid==0) //child
  31.     {
  32.         printf("child\n");
  33.         close(pipe1[1]); //close pipe1 write
  34.         close(pipe2[0]); //close pipe2 read
  35.         //write data to parent
  36.         child_process(pipe1[0], pipe2[1]);
  37.     } else if(pid > 0) //parent
  38.     {
  39.         printf("parent\n");
  40.         close(pipe1[0]); //close pipe1 read
  41.         close(pipe2[1]); //close pipe2 write
  42.         //read data frome child
  43.         parent_process(pipe2[0],pipe1[1]);
  44.         printf("next waitpid\n");
  45.         waitpid(pid, NULL, 0);
  46.         printf("waitpid over\n");
  47.     }
  48.     return EXIT_SUCCESS;
  49. }

  50. void parent_process(int readfd, int writefd)
  51. {
  52.     char buf[1024];
  53.     printf("next parent read\n");
  54.     read(readfd, buf, sizeof(buf));
  55.     printf("parent read_buf=%s",buf);

  56.     sleep(1);
  57.     write(writefd, "hello,world222\n",strlen("hello,world222\n")+1);
  58. }

  59. void child_process(int readfd, int writefd)
  60. {
  61.     char buf[1024];
  62.     sleep(1);
  63.     printf("next child write\n");
  64.     write(writefd, "hello,world111\n",strlen("hello,world111\n")+1);

  65.     printf("next child read\n");
  66.     read(readfd, buf, sizeof(buf));
  67.     printf("child read_buf=%s",buf);
  68. }

4.代码打包
pipe.rar(下载后改名为pipe.tar.gz)
5. socketpair
linux提供了另外一种实现双向管道的方法socketpair
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <string.h>
  5. #include <sys/types.h> /* See NOTES */
  6. #include <sys/socket.h>

  7. //child--->pipe-->parent
  8. //child<---pipe<--parent
  9. void parent_process(int readfd, int writefd);
  10. void child_process(int readfd, int writefd);

  11. int main ( int argc, char *argv[] )
  12. {
  13.     int sockfd[2];
  14.     pid_t pid;
  15.     char buf[1024];
  16.     if((socketpair(AF_LOCAL,SOCK_STREAM,0, sockfd)) < 0)
  17.     {
  18.         perror("socketpair error\n");
  19.         return -1;
  20.     }

  21.     printf("next fork\n");
  22.     if( (pid = fork()) < 0)
  23.     {
  24.         perror("fork error\n");
  25.         return -1;
  26.     } else if(pid==0) //child
  27.     {
  28.         printf("child\n");
  29.         close(sockfd[1]);
  30.         child_process(sockfd[0], sockfd[0]);     //既可读也可以写
  31.     } else if(pid > 0) //parent
  32.     {
  33.         printf("parent\n");
  34.         close(sockfd[0]);
  35.         //read data frome child
  36.         parent_process(sockfd[1], sockfd[1]);   //既可读也可以写
  37.         printf("next waitpid\n");
  38.         waitpid(pid, NULL, 0);
  39.         printf("waitpid over\n");
  40.     }
  41.     return EXIT_SUCCESS;
  42. }

  43. void parent_process(int readfd, int writefd)
  44. {
  45.     char buf[1024];
  46.     printf("next parent read\n");
  47.     read(readfd, buf, sizeof(buf));
  48.     printf("parent read_buf=%s",buf);

  49.     sleep(1);
  50.     write(writefd, "hello,world222\n",strlen("hello,world222\n")+1);
  51. }

  52. void child_process(int readfd, int writefd)
  53. {
  54.     char buf[1024];
  55.     sleep(1);
  56.     printf("next child write\n");
  57.     write(writefd, "hello,world111\n",strlen("hello,world111\n")+1);

  58.     printf("next child read\n");
  59.     read(readfd, buf, sizeof(buf));
  60.     printf("child read_buf=%s",buf);
  61. }
socketpair更简洁明了

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