zoukankan      html  css  js  c++  java
  • 进程通信-管道创建

    管道通信

    管道是单向的、先进先出的,由队列来实现,它把一个进程的输出和另一个进程的输入连接在一起

    一个进程(写进程)在管道的尾部写入数据,另一个进程(读进程)从管道的头部读出数据

    管道包括无名管道和有名管道。前者用于父进程和子进程间的通信,后者可用于运行于同一系统的任意两个进程间的通信。

    无名管道

    无名管道由pipe()函数创建

    int pipe(int fd[2]);//创建管道,为系统调用:unistd.h

    创建成功返回0,失败返回-1

    创建两个文件描述符:fd[0]用于读管道,fd[1]用于写管道

    注意:

    管道是创建在内存中的,进程结束,空间释放,管道就不存在了

    管道中的东西,读完了就删除了

    如果管道没有东西可读,就会读堵塞

    关闭管道,close关闭两个文件描述符

     

    必须在系统调用fork()前调用pipe(),否则子进程将不会继承文件描述符(子父各创建了一个管道)

    无名管道源代码

    #include <stdio.h>
    #include<malloc.h>
    #include <string.h>
    #include <stdlib.h>
    #include <fcntl.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <unistd.h>
    
    
    int  main()
    {
        int fd[2];
        int fd1;
        int ret;
        int i;
        char a[100];
        char b[10] = "123456";
        ret = pipe(fd);//管道创建必须在fork()函数之前
        if (ret < 0)
        {
            printf("创建管道失败
    ");
    
        }
        else {
            printf("创建管道成功
    ");
        }
    
        fd1 = fork();
    
        if (fd1 == 0)//子进程
        {
    
            printf("正在读取
    ");
            i = read(fd[0], a, sizeof(a));
            printf("已接受%s
    ", a);
            close(fd[0]);
        }
        if (fd1 > 0)//父进程
        {
    
            write(fd[1], b, sizeof(b));
    
            printf("已发送123456
    ");
            close(fd[1]);
        }
    
    
        return 0;
    
    
    
    }

    有名管道

    1、创建这个文件节点,不可以通过open函数,open函数只能创建普通文件,不能创建特殊文件(管道-mkdifo,套接字-socket,字符设备文件-mknod,块设备文件-mknod,符号链接文件-ln-s,目录文件 mkdir)

    2、管道文件只有inode号,不占磁盘块空间,和套接字、字符设备文件、块设备文件一样。普通文件和符号链接文件及目录文件,不仅有inode号,还占磁盘块空间

    3、mkfifo 用来创建管道文件的节点,没有在内核中创建管道

    只有通过open函数打开这个文件时才会在内核空间创建管道

    mkfifo

    函数形式 :int mkfifo(const char *filename,mode_t mode);

    功能:创建管道文件

    参数:管道文件文件名,权限,创建的文件权限仍然和umask有有关系

    返回值:创建成功返回0,创建失败返回-1

     代码如下,创建3个.c文件

    //创建管道节点 1.c
    #include <stdio.h>
    #include<malloc.h>
    #include <string.h>
    #include <stdlib.h>
    #include <fcntl.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <unistd.h>
    int main()
    {
    
    int fd;
        fd = mkfifo("./write_mkfifo",0777);
        if (fd < 0)
        {
            printf("创建管道节点失败");
            return -1;
    
        }
        else
            printf("创建管道节点成功");
    
    }
    //创建一个进程写管道  write.c
    #include <stdio.h>
    #include<malloc.h>
    #include <string.h>
    #include <stdlib.h>
    #include <fcntl.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <unistd.h>
    
    int  main()
    {
        int fd;
        char a[10]="123456";
        fd = open("./write_mkfifo", O_WRONLY);
        if (fd < 0)
        {
            printf("打开管道失败
    ");
        }
        else 
        {
            printf("打开管道成功
    ");
        }
    
        write(fd,a,sizeof(a));
        printf("已发送数据到管道
    ");
    
    
    
    
    }
         
    //创建一个进程读管道 read.c
    #include <stdio.h>
    #include<malloc.h>
    #include <string.h>
    #include <stdlib.h>
    #include <fcntl.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <unistd.h>
    
    int  main()
    {
        int fd;
        char b[10];
        fd = open("./write_mkfifo", O_RDONLY);
        if (fd < 0)
        {
            printf("打开管道失败
    ");
        }
        else 
        {
            printf("打开管道成功
    ");
        }
        read(fd,b,sizeof(b));
        printf("接收数据成功:%s
    ",b);
        close(fd);
    
        
    
    
    
    
    }

    结果如下

  • 相关阅读:
    动态页面技术----EL技术、JSTL技术,javaEE的开发模式
    动态页面技术----JSP技术
    会话技术Cookie&Session
    HttpServletRequest
    设计模式和抽象类、方法
    类的继承
    类与对象
    面向对象和面向过程的区别
    PHP-错误处理
    PHP-文件加载
  • 原文地址:https://www.cnblogs.com/cyyz-le/p/11048061.html
Copyright © 2011-2022 走看看