Linux进程间通信——pipe应用实例

    管道(pipe):管道可用于具有亲缘关系的进程间的通信,是一种半双工的方式,数据只能单向流动,允许一个进程和另一个与它有共同祖先的进程之间进行通信。

PIPE模块程序一

下面模块代码是在主函数中创将一个进程,在子进程中往管道中写数据,在父进程中读取数据,也就是一对一的读写操作。


 
 
  1. /*=============================================================================
  2. # FileName: pipe1.c
  3. # Desc: an example of pipe communication application
  4. # Author: Licaibiao
  5. # Version:
  6. # LastChange: 2017-01-09
  7. # History:
  8. =============================================================================*/
  9. #include <sys/wait.h>
  10. #include <assert.h>
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <unistd.h>
  14. #include <string.h>
  15. int main( int argc, char *argv[])
  16. {
  17. pid_t pid;
  18. int fd[ 2];
  19. int read_count = 0;
  20. int i;
  21. char read_buffer[ 10] = { 0};
  22. char write_buffer[ 10] = { 0};
  23. /*create pipe*/
  24. if (pipe(fd) < 0)
  25. {
  26. printf( "Create pipe failed\n");
  27. return -1;
  28. }
  29. /*create process*/
  30. if ((pid = fork()) < 0)
  31. {
  32. printf( "Fork failed\n");
  33. return -1;
  34. }
  35. /* child */
  36. if (pid == 0)
  37. {
  38. printf( "[child]Close read endpoint...\n");
  39. /* close read */
  40. close(fd[ 0]);
  41. for(i= 0;i< 10;i++)
  42. {
  43. write_buffer[i]=i;
  44. }
  45. write(fd[ 1],write_buffer,i);
  46. }
  47. /*father*/
  48. else
  49. {
  50. printf( "[parent]Close write endpoint...\n");
  51. /* close write */
  52. close(fd[ 1]);
  53. read_count = read(fd[ 0], read_buffer, 10);
  54. printf( "father process read data\n");
  55. for(i= 0; i<read_count; i++)
  56. {
  57. printf( "read_buffer[%d] = %d\n",i,read_buffer[i]);
  58. }
  59. }
  60. }
程序执行结果:


 
 
  1. root@ubuntu:/home/share/pipe # gcc pipe1.c -o test
  2. root@ubuntu:/home/share/pipe # ./test
  3. [parent]Close write endpoint...
  4. [child]Close read endpoint...
  5. father process read data
  6. read_buffer[ 0] = 0
  7. read_buffer[ 1] = 1
  8. read_buffer[ 2] = 2
  9. read_buffer[ 3] = 3
  10. read_buffer[ 4] = 4
  11. read_buffer[ 5] = 5
  12. read_buffer[ 6] = 6
  13. read_buffer[ 7] = 7
  14. read_buffer[ 8] = 8
  15. read_buffer[ 9] = 9


PIPE模块程序二

    下面的程序是在主进程中创建了三个子进程,在子进程中写入数据,在父进程中读出数据,这里使用的是多进程写入,因此需要对文件进程加锁,这里使用的了lockf函数。


 
 
  1. /*=============================================================================
  2. # FileName: pipe2.c
  3. # Desc: three process write piep and father process read data
  4. # Author: Licaibiao
  5. # Version:
  6. # LastChange: 2017-01-09
  7. # History:
  8. =============================================================================*/
  9. #include <sys/wait.h>
  10. #include <assert.h>
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <unistd.h>
  14. #include <string.h>
  15. #include <unistd.h>
  16. #include <signal.h>
  17. #include <stdio.h>
  18. int main( void)
  19. {
  20. int fd[ 2];
  21. int i;
  22. int pid[ 3]={ 1, 1, 1};
  23. char outpipe[ 100],inpipe[ 100];
  24. pipe(fd);
  25. /* create three process */
  26. for(i= 0;i< 3;i++)
  27. {
  28. pid[i]=fork( );
  29. if(pid[i]== 0)
  30. break;
  31. }
  32. if(pid[ 0]== 0)
  33. {
  34. lockf(fd[ 1],F_LOCK, 0);
  35. sprintf(outpipe, "child 1 process is sending message!");
  36. write(fd[ 1],outpipe, 50);
  37. sleep( 5);
  38. lockf(fd[ 1],F_ULOCK, 0);
  39. exit( 0);
  40. }
  41. if(pid[ 1]== 0)
  42. {
  43. lockf(fd[ 1],F_LOCK, 0);
  44. sprintf(outpipe, "child 2 process is sending message!");
  45. write(fd[ 1],outpipe, 50);
  46. sleep( 5);
  47. lockf(fd[ 1],F_ULOCK, 0);
  48. exit( 0);
  49. }
  50. if(pid[ 2]== 0)
  51. {
  52. lockf(fd[ 1],F_LOCK, 0);
  53. sprintf(outpipe, "child 3 process is sending message!");
  54. write(fd[ 1],outpipe, 50);
  55. sleep( 5);
  56. lockf(fd[ 1],F_ULOCK, 0);
  57. exit( 0);
  58. }
  59. wait( 0);
  60. read(fd[ 0],inpipe, 50);
  61. printf( "%s\n",inpipe);
  62. read(fd[ 0],inpipe, 50);
  63. printf( "%s\n",inpipe);
  64. read(fd[ 0],inpipe, 50);
  65. printf( "%s\n",inpipe);
  66. return 0;
  67. }
这里创建了三个进程,进程执行的顺序是不确定的,当pipe被锁定的时候,其他的请求操作这个文件的进程将被阻塞,直到pipe被解除锁定之后,其他的进程之间进行竞争决定谁先谁后执行。多次运行结果下:


 
 
  1. root@ubuntu:/home/share/pipe # gcc pipe2.c -o test
  2. root@ubuntu:/home/share/pipe # ./test
  3. child 3 process is sending message!
  4. child 2 process is sending message!
  5. child 1 process is sending message!
  6. root@ubuntu:/home/share/pipe # ./test
  7. child 3 process is sending message!
  8. child 2 process is sending message!
  9. child 1 process is sending message!
  10. root@ubuntu:/home/share/pipe # ./test
  11. child 3 process is sending message!
  12. child 2 process is sending message!
  13. child 1 process is sending message!
  14. root@ubuntu:/home/share/pipe # ./test
  15. child 2 process is sending message!
  16. child 3 process is sending message!
  17. child 1 process is sending message!
  18. root@ubuntu:/home/share/pipe # ./test
  19. child 3 process is sending message!
  20. child 2 process is sending message!
  21. child 1 process is sending message!
  22. root@ubuntu:/home/share/pipe # ./test
  23. child 3 process is sending message!
  24. child 2 process is sending message!
  25. child 1 process is sending message!
  26. root@ubuntu:/home/share/pipe # ./test
  27. child 3 process is sending message!
  28. child 2 process is sending message!
  29. child 1 process is sending message!
  30. root@ubuntu:/home/share/pipe # ./test
  31. child 3 process is sending message!
  32. child 2 process is sending message!
  33. child 1 process is sending message!
  34. root@ubuntu:/home/share/pipe # ./test
  35. child 1 process is sending message!
  36. child 3 process is sending message!
  37. child 2 process is sending message!
  38. root@ubuntu:/home/share/pipe #
如果要固定执行先后顺序,可以把子进程一个一个的分开来创建,每创建一个子进程就请求操作pipe,最后在父进中读取就可以了。

PIPE模块程序三

下面的程序是两个进程写入,两个进程读取,在pipe中写入的数据,其他的进程再读取的时候,将读取不到数据。程序代码如下:


 
 
  1. /*=============================================================================
  2. # FileName: pipe3.c
  3. # Desc: two process write into pipe and two process read from pipe
  4. # Author: Licaibiao
  5. # Version:
  6. # LastChange: 2017-01-09
  7. # History:
  8. =============================================================================*/
  9. #include <sys/wait.h>
  10. #include <assert.h>
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <unistd.h>
  14. #include <string.h>
  15. #include <unistd.h>
  16. #include <signal.h>
  17. #include <stdio.h>
  18. int main( void)
  19. {
  20. int fd[ 2], i;
  21. int pid[ 3] = { 1, 1, 1};
  22. char outpipe[ 100],inpipe[ 100];
  23. pipe(fd);
  24. for(i= 0;i< 3;i++)
  25. {
  26. pid[i]=fork( );
  27. if(pid[i]== 0)
  28. break;
  29. }
  30. if(pid[ 0]== 0)
  31. {
  32. lockf(fd[ 1],F_LOCK, 0);
  33. sprintf(outpipe, "child 1 process is sending message!");
  34. write(fd[ 1],outpipe, 50);
  35. sleep( 5);
  36. lockf(fd[ 1],F_ULOCK, 0);
  37. exit( 0);
  38. }
  39. if(pid[ 1]== 0)
  40. {
  41. lockf(fd[ 1],F_LOCK, 0);
  42. sprintf(outpipe, "child 2 process is sending message!");
  43. write(fd[ 1],outpipe, 50);
  44. sleep( 5);
  45. lockf(fd[ 1],F_ULOCK, 0);
  46. exit( 0);
  47. }
  48. if(pid[ 2]== 0)
  49. {
  50. lockf(fd[ 0],F_LOCK, 0);
  51. read(fd[ 0],inpipe, 50);
  52. printf( "Child 3 read:\n%s\n",inpipe);
  53. lockf(fd[ 0],F_ULOCK, 0);
  54. exit( 0);
  55. }
  56. wait( 0);
  57. read(fd[ 0],inpipe, 50);
  58. printf( "Parent read:\n%s\n",inpipe);
  59. exit( 0);
  60. }

执行结果如下:


 
 
  1. root@ubuntu:/home/share/pipe # vim pipe3.c
  2. root@ubuntu:/home/share/pipe # gcc pipe3.c -o test
  3. root@ubuntu:/home/share/pipe # ./test
  4. Child 3 read:
  5. child 2 process is sending message!
  6. Parent read:
  7. child 1 process is sending message!
  8. root@ubuntu:/home/share/pipe # ./test
  9. Child 3 read:
  10. child 2 process is sending message!
  11. Parent read:
  12. child 1 process is sending message!
  13. root@ubuntu:/home/share/pipe # ./test
  14. Child 3 read:
  15. child 2 process is sending message!
  16. Parent read:
  17. child 1 process is sending message!
  18. root@ubuntu:/home/share/pipe # ./test
  19. Child 3 read:
  20. child 2 process is sending message!
  21. Parent read:
  22. child 1 process is sending message!





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值