欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  科技

进程通信-管道创建

程序员文章站 2022-09-28 08:06:09
管道通信 管道是单向的、先进先出的,由队列来实现,它把一个进程的输出和另一个进程的输入连接在一起 一个进程(写进程)在管道的尾部写入数据,另一个进程(读进程)从管道的头部读出数据 管道包括无名管道和有名管道。前者用于父进程和子进程间的通信,后者可用于运行于同一系统的任意两个进程间的通信。 无名管道 ......

管道通信

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

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

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

 

无名管道

无名管道由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("创建管道失败\n");

    }
    else {
        printf("创建管道成功\n");
    }

    fd1 = fork();

    if (fd1 == 0)//子进程
    {

        printf("正在读取\n");
        i = read(fd[0], a, sizeof(a));
        printf("已接受%s\n", a);
        close(fd[0]);
    }
    if (fd1 > 0)//父进程
    {

        write(fd[1], b, sizeof(b));

        printf("已发送123456\n");
        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("打开管道失败\n");
    }
    else 
    {
        printf("打开管道成功\n");
    }

    write(fd,a,sizeof(a));
    printf("已发送数据到管道\n");




}
     
//创建一个进程读管道 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("打开管道失败\n");
    }
    else 
    {
        printf("打开管道成功\n");
    }
    read(fd,b,sizeof(b));
    printf("接收数据成功:%s\n",b);
    close(fd);

    




}

结果如下

进程通信-管道创建