• 进程间通信之管道


    管道是类似于文件读写进程间通信的方式,也是比较古老的进程间通信方式.管道的使用需要在创建管道文件,进程通过对该文件读写来完成通信,管道文件并不会占用磁盘空间.必须管道内有信息的时候才能对管道内进行读取.否则会IO堵塞.程序被堵塞.而且管道两端被打开以后才可以进行读写,否则IO堵塞.个人比较喜欢使用信号和管道配合使用,当对管道进行了写操作以后发送信号给相关进程,当相关信号来了以后对管道文件进行读取.这样有效的避免了IO堵塞造成程序没法进行其他的操作.

    管道分为有名管道(FIFO)和无名管道(PIPE):

    1. 管道使用的一般步骤:
    2. 初始化管道文件系统
    3. 注册和加载管道
    4. 建立读和写管道
    5. 进行读写
    6. 使用结束以后关闭管道文件

    一,无名管道:只能在有亲缘关系的进程之间才能使用.

    头文件<unistd.h>
    int pipe(int filedes[2]);//建立无名管道(父子进程间的通信)

    1. int p[2]; //管道文件描述符
    2. char buf[16];
    3. char buf0[16];
    4. pid_t pid;
    5. strcpy(buf,"Hello World!");
    6. pipe(p);//注册管道
    7. pid = fork()
    8. if(pid > 0){
    9. write(p[1], buf, strlen(buf));  //对管道进行写操作
    10. //关闭管道文件描述符
    11. close(p[1]);
    12. close(p[2]);
    13. }
    14. if(pid == 0){
    15. read(p[0], buf0, sizeof(buf0));//对管道进行读操作
    16. printf("%s ", buf0);
    17. close(p[0]);
    18. close(p[1]);
    19. }
    20. if(pid < 0){
    21. exit(1);
    22. }

    二,有名管道:任意进程均可通过此方式进行通信

    头文件<sys/types.h> <sys/stat.h>//建立有名管道(无关进程的通信)
    int mkfifo(const char * pathname,int mode);
    根据pathname创建特殊的FIFO文件,mode是该文件的权限
    返回值:0成功,-1失败

    1 #include <stdio.h>
    2 #include <stdlib.h>
    3 #include <sys/types.h>
    4 #include <sys/stat.h>
    5 #include <fcntl.h>
    6 #include <string.h>
    7 #include <errno.h>
    8 #include <unistd.h>
    9
    10 #define FIFO_PATH "/home/linux/myfifo"   //管道文件
    11
    12
    13 int main(int arge,char *argv[])
    14 {
    15 int fdw = 0; //读文件描述符
    16 int fdr = 0;//写文件描述符
    17 char cwrite[8] = {0};
    18
    19 if(arge != 2){
    20 printf("参数输入错误 ");
    21 return -1;
    22 }
    23
    24 if(mkfifo(FIFO_PATH,0666) < 0 && errno != EEXIST){//注册管道文件
    25 printf("创建错误 ");
    26 return -2;
    27 }else{
    28 fdw = open(FIFO_PATH, O_CREAT | O_WRONLY,0666);//打开写管道
    29 fdr = open(argv[1],O_CREAT | O_RDONLY,0666);//打开读管道
    30 //进行读写管道的操作
    31 if(fdw > 0){
    32
    33 if(fdr > 0){
    34 while(read(fdr,cwrite,7) > 0){
    35 write(fdw,cwrite,7);
    36 memset(cwrite,0,sizeof(cwrite));
    37 }
    38
    39 }else{
    40 printf("%s文件打开失败 ",argv[1]);
    41 return -3;
    42 }
    43
    44 }else{
    45 printf("管道打开失败 ");
    46 return -4;
    47 }
    48 }
    49 //关闭文件描述符
    50 close(fdw);
    51 close(fdr);
    52
    53 return 0;
    54 }

  • 相关阅读:
    反射
    java 验证码识别
    Spring boot + mybatis + orcale
    JVM内存模型及垃圾回收的研究总结
    Java的Array和ArrayList
    Java中最常见的十道面试题
    session和cookie
    Hibernate的load()和get()区别
    ajax跨域获取网站json数据
    对于Spring的IOc和DI的理解
  • 原文地址:https://www.cnblogs.com/CHYI1/p/5400717.html
Copyright © 2020-2023  润新知