zoukankan      html  css  js  c++  java
  • 【linux高级程序设计】(第九章)进程间通信-管道 3

    有名管道

    无名管道和有名管道:

    1. 管道是特殊类型的文件,在满足先入先出的原则写可以读写,不能定位读写位置。

    2.管道是单向的。

    3.无名管道阻塞于读写位置,而有名管道阻塞在创建位置

    4.无名管道一般只用于亲缘关系进程间通信;有名管道以磁盘文件的方式存在,可以实现本机任意两进程间通信。

    shell创建有名管道

    mknod 管道名 p  //创建名为PIPETEST的有名管道 mknod为命令 p是参数,表示有名管道

    指令 > 管道名 &   //将指令结果输入到到管道文件中

    指令 < 管道名      //以指定管道名中的内容做为输入

    编程实现有名管道

    int mkfifo (__const char *__path, __mode_t __mode):建立的有名管道文件必须之前不存在, mode是该文件的权限。成功返回0,否则返回-1.

    通过read(), write()实现读写操作。

    其阻塞方式见下图(我懒得打字了,就上图吧....)

    例子:

    写进程

    #include<stdio.h>
    #include<unistd.h>
    #include<sys/types.h>
    #include<fcntl.h>
    #include<string.h>
    #include<stdlib.h>
    #include<errno.h>
    #include<sys/stat.h>
    
    #define FIFO_NAME "/tmp/my_fifo"       //要创建的有名管道的路径
    int main(int argc, char * argv[])
    {
        int pipe_fd;
        int res;
        char buffer[] = "hello world!";
        if(access(FIFO_NAME, F_OK) == -1)   //文件是否存在
        {
            res = mkfifo(FIFO_NAME, 0766);    //创建管道
            if(res != 0)
            {
                fprintf(stderr, "Could not create fifo %s
    ", FIFO_NAME);
                exit(EXIT_FAILURE);
            }
        }
        printf("Process %d opening FIFO O_WRONLY
    ", getpid());
        pipe_fd = open(FIFO_NAME, O_WRONLY);    //打开有名管道
        printf("the file's descriptor is %d
    ", pipe_fd);
        if(pipe_fd != -1)
        {
            res = write(pipe_fd, buffer, sizeof(buffer));  //写数据
            if(res == -1)
            {
                fprintf(stderr, "Write error on pipe
    ");
                exit(EXIT_FAILURE);
            }
            printf("write data is %s, %d bytes is write
    ", buffer, res);
            close(pipe_fd);
        }
        else
            exit(EXIT_FAILURE);
        printf("Process %d finished
    ", getpid());
        exit(EXIT_SUCCESS);
    }

    读进程

    #include<stdio.h>
    #include<unistd.h>
    #include<sys/types.h>
    #include<fcntl.h>
    #include<string.h>
    #include<stdlib.h>
    #include<errno.h>
    #include<sys/stat.h>
    
    #define FIFO_NAME "/tmp/my_fifo"       //要创建的有名管道的路径
    int main(int argc, char * argv[])
    {
        int pipe_fd;
        int res;
        char buffer[4096];
        int bytes_read = 0;
        memset(buffer, '', sizeof(buffer));
        printf("Process %d opening FIFO O_RDONLY
    ", getpid());
        pipe_fd = open(FIFO_NAME, O_RDONLY);    //打开有名管道
        printf("the file's descriptor is %d
    ", pipe_fd);
        if(pipe_fd != -1)
        {
            bytes_read = read(pipe_fd, buffer, sizeof(buffer));
            printf("the read data is %s
    ", buffer);
            close(pipe_fd);
        }
        else
            exit(EXIT_FAILURE);
        printf("Process %d finished, %d bytes read
    ", getpid(), bytes_read);
        exit(EXIT_SUCCESS);
    }

    运行时,先在一个终端运行写进程,此时写进程会阻塞。

    ctrl+alt+[F1-F6]切换终端,在新终端运行读进程。

    读进程端结果为

    再切换回原终端,写进程也执行完毕。

  • 相关阅读:
    学习angularjs的ng-hide和ng-disabled
    Angularjs实现select的下拉列表
    练习ng-show和ng-hide的方法
    练习angularjs的ng-click的应用
    ng-include文件实现ng-repeat
    JQuery加载html网页
    指定时间内网站访问次数的监控
    AWK 技巧(取倒列,过滤行,匹配,不匹配,内置变量等)
    Linux下FastDFS分布式存储-总结及部署记录
    Linux下IP SAN共享存储操作记录
  • 原文地址:https://www.cnblogs.com/dplearning/p/4681080.html
Copyright © 2011-2022 走看看