LINUX进程间通信(IPC)–管道

  • Post author:
  • Post category:linux





一、无 名管道

管道,通常指无名管道,是UNIX系统IPC最古老的形式



特点:

  • 半双工(即数据只能在一个方向上流动),具有固定的读端和写端。
  • 它只能用于具有亲缘关系的进程之间的通信(也是父子进程或者兄弟进程之间)。
  • 它可以看成是一种特殊的文件,对于它的读写也可以使用普通的read、write 等函数。但是它不是普通的文件,并不属于其他任何文件系统,并且只存在于内存中。



要点:


1、#include // 头文件



2、int fd[2]; // fd[0]:读端 / fd[1]:写端

3、 pipe(fd) //创建管道



4、传输信息时,发送端先关闭读端fd[0],再进行写操作

接收端反之,close(fd[1]); read( );



demo:无名管道,父进程–>子进程

#include<stdio.h>
#include<unistd.h> 
#include<stdlib.h>

int main()
{
        int fd[2];  //fd[0]:读端  fd[1]:写端
        pid_t  pid;  //typedef定义类型,short
        char buf[128];

        if(pipe(fd) == -1) //创建管道,创建成功返回0,失败返回-1
        {
                printf("creat pipe failed\n");
        }
        
        pid = fork();//创建进程
        if(pid<0)
        {
                printf("creat child failed\n");
        }
        else if(pid >0) //父进程
        {
                printf("this is father\n");
                close(fd[0]); //关读端
                write(fd[1],"hello word from father",30); //写消息
                wait(); //等待子进程退出
        }
        else
        {
                printf("this is child\n");
                close(fd[1]); //关写端
                read(fd[0],buf,128); //读消息
                printf("read from father:%s\n",buf);
                exit(0);
        }

        return 0;
}




二、FIFO(命名管道)



特点

  • FIFO可以在无关的进程之间交换数据,与无名管道不同。
  • FIFO有路径名与之相关联,它以一种特殊设备文件形式存在于文件系统中。



FIFO创建

创建命名管道时,可能会存在管道名已存在造成创建失败退出现象

1、mkfifo() 创建命名管道

2、perror()函数 显示错误原因到标准输出

//int mkfifo(const char *pathname,mode_t mode)
//mode与open函数中的mode相同
int main()
{
        if(mkfifo("./guandao",0600) == -1 && errno != EEXIST)
        {
                printf("mkfifo failer\n");
                perror("why");
        }
        return 0;
}



FIFO通信传输

当open一个FIFO时,是否设置非阻塞标(O_NONBLOCK)有区别:

1、若没有指定,只读open(O_RDONLY)要阻塞到某个其他的进程为写(write)而打开此FIFO。反之只写打开(O_WRONLY),要等到另一个文件只读打开。

(eg:——-将一个只写打开,等待另一个write运行时,实现信息传输)

2、若指定O_NONBLOCK,则只读open立即返回,而只写open将出错返回-1

<<FIFO的通信方式类似于在进程中使用文件来传输数据,只不过FIFO类型文件同时具有管道的特性。在数据读出时,FIFO管道中同时清除数据,并且“先进先出”。>>



demo: FIFO 阻塞通信

fifo_read.c

#include<stdio.h>
#include<stdlib.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<errno.h> //perror
#include<fcntl.h>
int main()
{
        if(mkfifo("./guandao",0600) == -1 && errno != EEXIST)
        {
                printf("mkfifo failer\n");
                perror("why");
        }
        int fd = open("./guandao",O_RDONLY);//以只读打开
        printf("open success\n");
        return 0;

}

fifo_write.c

int main()
{
        int fd = open("./guandao",O_WRONLY); //以只写打开
        printf("write success\n");
        return 0;
}

在两个终端里用 gcc 分别编译运行上面两个文件,只运行其中一个会阻塞等待,当另一个运行时,两个进程才会打印出相应内容。

如果通过FIFO,两个进程传递信息,通过分别 read(fd,buf,size)及write(fd,buf,size)进行<参考收藏博文demo代码>



版权声明:本文为qq_44370382原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。