找回密码
 立即注册
首页 业界区 安全 管道通信

管道通信

煅汾付 2025-6-11 15:26:20
管道通信

Linux系统提供了一种通信方式,名字叫做管道通信,顾名思义,管道是单向的,比如水管、燃气管道等,换个说法就是管道是采用半双工通信的,也就是同一时刻只能完成发送数据或者接收数据。
匿名管道

用匿名管道实现,创建匿名管道,在子进程中将I am child,hello!!!写入管道,在父进程中读取管道内容并输出
  1. /******************************************************
  2. *
  3. *  filename:pipe
  4. *  author  :zzlyx1239@126.com
  5. *  function:进程间通信
  6. *  date    :2025.4.1
  7. *  brief   :匿名管道
  8. *  note    :none
  9. *
  10. *  CopyRight zzlyx1239@126.com 2025.4.1
  11. ***********************************************************/
  12. #include <unistd.h>
  13. #include <sys/types.h>
  14. #include <sys/stat.h>
  15. #include <fcntl.h>
  16. #include <sys/wait.h>
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <string.h>
  20. #include <errno.h>
  21. int main()
  22. {
  23.     //1.创建一个匿名管道
  24.     int pipefd[2]={0};
  25.     int ret=pipe(pipefd);
  26.     if(ret=-1)
  27.     {
  28.         fprintf(stderr,
  29.             "creat pipe error,errno=%d,%s/n",
  30.             errno,stderror(errno));
  31.         return -1;
  32.     }
  33.     //2.创建子进程
  34.     int child_pid=fork();
  35.     //3.分析当前id是父进程or子进程or创建失败
  36.     if(child_pid>0)//父进程
  37.     {
  38.         char recebuf[128]={0};
  39.         read(pipefd[0],recebuf,sizeof(recebuf));
  40.         printf("I am parent,my child say :%s\n",recebuf);
  41.         wait(NULL);
  42.     }
  43.     else if(child_pid=0)
  44.     {
  45.         char sentbuf[128]="I am child,hello!!!";
  46.         write(pipefd[1],sentbuf,strlen(sentbuf));
  47.     }
  48.     else
  49.     {
  50.         fprintf(stderr, "fork error,errno:%d,%s\n",errno,strerror(errno));
  51.                 exit(2); //exit函数可以终止进程,并把进程的终止状态提供给该进程的父进程
  52.     }
  53.     return 0;
  54. }
复制代码
命名管道

由于匿名管道只适合一对一、并且具有亲缘关系的进程间通信,导致局限性较大,所以Linux系统下还提供了另一种管道,名称叫做命名管道,也可以称为有名管道、具名管道等。
相比于匿名管道而言,命名管道有自己的文件名,可以被open,同样也支持read/write访问。当然,管道文件毕竟不是普通文件,由于管道的特性的原因,所以管道是不支持指定位置读取数据的,也就意味着不能对管道文件进行lseek操作。
  1. /******************************************************
  2. *
  3. *  filename:fifo
  4. *  author  :zzlyx1239@126.com
  5. *  function:进程间通信
  6. *  date    :2025.4.1
  7. *  brief   :匿名管道
  8. *  note    :none
  9. *
  10. *  CopyRight zzlyx1239@126.com 2025.4.1
  11. ***********************************************************/
  12. #include <unistd.h>
  13. #include <sys/types.h>
  14. #include <sys/stat.h>
  15. #include <fcntl.h>
  16. #include <sys/wait.h>
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <string.h>
  20. #include <errno.h>
  21. int main()
  22. {
  23.     //1.创建一个命名管道,文件名为fifo,权限为0664
  24.     int ret =mkfifo("./fifo",0664);
  25.     if(ret=-1)
  26.     {
  27.         fprintf(stderr, "fifo error,errno:%d,%s\n",errno,strerror(errno));
  28.                 exit(1); //exit函数可以终止进程
  29.     }
  30.     //2.打开命名管道文件
  31.     int fifo_fd =open("./fifo",O_RDWR);
  32.     if(fifo_fd=-1)
  33.     {
  34.         fprintf(stderr, "open fifo error,errno:%d,%s\n",errno,strerror(errno));
  35.                 exit(1); //exit函数可以终止进程
  36.     }
  37.     //3.向有名管道写入数据
  38.         ret = write(fifo_fd,"hello world",11);
  39.         if(ret != 11)
  40.         {
  41.                 printf("write error\n");
  42.                 return -1;
  43.         }
  44.         //4.关闭有名管道
  45.         close(fifo_fd);
  46.         return 0;
  47. }
复制代码
在 /tmp 目录下创建一条命名管道,命名管道的名称用户决定,然后设计两个程序,要求进程A获取当前系统时间(time-->ctime)并写入到命名管道,进程B从命名管道中读取数据并存储在一个名字叫做log.txt的文本中。
psB.c
  1. /******************************************************
  2. *
  3. *  filename:psB.c
  4. *  author  :zzlyx1239@126.com
  5. *  function:
  6. *  date    :2025.4.1
  7. *  brief   :取管道中的数据写入日志文件中
  8. *  note    :none
  9. *
  10. *  CopyRight zzlyx1239@126.com 2025.4.1
  11. ***********************************************************/
  12. #include <unistd.h>
  13. #include <sys/types.h>
  14. #include <sys/stat.h>
  15. #include <fcntl.h>
  16. #include <sys/wait.h>
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <string.h>
  20. #include <errno.h>
  21. #include <time.h>
  22. int main()
  23. {
  24.     //1.打开一个日志文件,文件名为log.txt
  25.     FILE * log_fp=fopen("./log.txt","wb+");
  26.     if(log_fp=NULL)
  27.     {
  28.         fprintf(stderr, "open log.txt error,errno:%d,%s\n",errno,strerror(errno));
  29.                 exit(1); //exit函数可以终止进程
  30.     }
  31.     //2.打开命名管道文件
  32.     FILE * fifo_fp =open("./fifo","r+");
  33.     if(fifo_fp=NULL)
  34.     {
  35.         fprintf(stderr, "open fifo error,errno:%d,%s\n",errno,strerror(errno));
  36.                 exit(1); //exit函数可以终止进程
  37.     }
  38.     //3.向有名管读取时间,写入log.txt
  39.     while(1)
  40.     {
  41.         char timebuf[128]={0};
  42.         fread(timebuf,sizeof(timebuf),1,fifo_fp);
  43.         fwrite(timebuf,sizeof(timebuf),1,log_fp);
  44.         bzero(timebuf,sizeof(timebuf));
  45.         sleep(1);
  46.     }
  47.         //4.关闭有名管道,关闭log.txt文件
  48.         close(fifo_fp);
  49.     fclose(log_fp);
  50.         return 0;
  51. }
复制代码
psA.c
  1. /******************************************************
  2. *
  3. *  filename:psA.c
  4. *  author  :zzlyx1239@126.com
  5. *  function:
  6. *  date    :2025.4.1
  7. *  brief   :向命名管道中写入系统时间
  8. *  note    :none
  9. *
  10. *  CopyRight zzlyx1239@126.com 2025.4.1
  11. ***********************************************************/
  12. #include <unistd.h>
  13. #include <sys/types.h>
  14. #include <sys/stat.h>
  15. #include <fcntl.h>
  16. #include <sys/wait.h>
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <string.h>
  20. #include <errno.h>
  21. int main()
  22. {
  23.     //1.创建一个命名管道,文件名为fifo,权限为0664
  24.     int ret =mkfifo("./fifo",0664);
  25.     if(ret=-1)
  26.     {
  27.         fprintf(stderr, "fifo error,errno:%d,%s\n",errno,strerror(errno));
  28.                 exit(1); //exit函数可以终止进程
  29.     }
  30.     //2.打开命名管道文件
  31.     int fifo_fd =open("./fifo",O_RDWR);
  32.     if(fifo_fd=-1)
  33.     {
  34.         fprintf(stderr, "open fifo error,errno:%d,%s\n",errno,strerror(errno));
  35.                 exit(1); //exit函数可以终止进程
  36.     }
  37.     //3.向有名管道写入数据
  38.     char * ptime;
  39.     while(1)
  40.     {
  41.         ptime=ctime(time(NULL));
  42.         write(fifo_fd,ptime,strlen(ptime));
  43.         sleep(1);
  44.     }
  45.         //4.关闭有名管道
  46.         close(fifo_fd);
  47.         return 0;
  48. }
复制代码
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册