Linux进程间通信:无名管道(pipe),有名管道(fifo)

☆管道说明:

为什么需要建立管道:进程与进程在应用层里面不能直接进行信息交互,必须通过内核来进行通信。

管道的作用:创建一个管道作为进程间信息交互的媒介,所以进程A就可以在管道中写入数据,进程B在从管道中读取数据,这样就可以实现进程A与进程B之间的通信。

无名管道与有名管道异同点:

相同点:

①都是半双工通信,只提供单向通信。比如两个进程都能访问这个管道里的内容,如果进程A往管道内写东西,那么进程B 就只能读取管道的内容;
②管道是基于字节流来通信的;
③依赖于文件系统,它的生命周期随进程的结束而结束;
④其本身自带同步互斥效果。

不同点:

无名管道:①只适用于带有亲缘关系的进程,比如父子进程;如果进程间没有任何关系,就不能使用无名管道。

                  ②只能实现一个进程写另一个进程读,而如果需要两者同时进行时,就得重新打开一个管道。

有名管道:①可以实现没有任何亲缘关系的进程间的通信,因为有名管道在使用前必须创建一个特殊文件名(mkfifo)来承接进程间的读和写;

                  ②可以实现进程A写,进程B读,也可以实现进程A读,进程B写,无需重新打开新的管道。
 

☆无名管道(pipe)

返回值:打开管道成功,返回0,打开失败,返回-1;

说明:fd[2]因为有读端和写端两个进程,所以有两个文件描述符,fd[0]为读端,fd[1]为写端,定义好文件描述符后,就使用pipe函数打开管道。

注意:一定要在调用fork之前打开管道,因为管道是属于父子进程共享管道。

妙招:fdp[0],0的形状像嘴巴,嘴巴就用来读,所以为读端;fd[1],1的形状像一直笔,笔用来写,所以为写端。

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
int main()
{
        int fd[2];//读端 写端
        char *buf = "gogogogogogogogo";
        pipe(fd);//打开管道
        printf("fd[0]=%d\n",fd[0]);//fd=3
        printf("fd[1]=%d\n",fd[1]);//fd=4
        int pid = fork();
        if(pid > 0){
                printf("father pid = %d\n",getpid());//父进程
                close(fd[0]);//写之前需关闭读端
                write(fd[1],buf,strlen(buf));//写端 写入数据
                close(fd[1]);//写入数据后关闭写端
        }else if(pid == 0){
                printf("child pid = %d\n",getpid());//子进程
                close(fd[1]);//读之前须关闭写端
                read(fd[0],buf,strlen(buf));//读端,读取数据
                printf("buf:%s\n",buf);//打印读取到的内容
                close(fd[0]);//读取数据后关闭读端
        }
        return 0;
}

☆有名管道(fifo) 

返回值:特殊文件创建成功,mkfifo返回0,创建失败,mkfifo返回-1。

说明:① 在使用有名管道之前,使用mkfifo函数创建一个特殊文件来承接进程的读和写,可以先在命令行中先创建这个文件,也可以在编辑代码的时候创建;

 if(mkfifo("fifo",0600) == 0){
                printf("mkfifo success!\n");
//代码中直接使用mkfifo创建承接文件fifo

           ② 在编译时,如果只运行read.c文件,不会有内容出现,需要同事编译write.c文件,才能编译出文件内容;

           ③ 在read.c文件中,对“fifo”文件的权限只需可读即可“O_RDONLY”,在write.c文件中,对‘fifo’文件的权限只需要可读即可“O_WRONLY”。

//先在命令行中使用mkfifo函数创建一个名为fifo的特殊文件
dhw@dhw-virtual-machine:~$ mkfifo fifo   

//创建write.c文件,作为写入文件
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

int main()
{
        char *buf = "hello baby!";
        int fd = open("fifo",O_WRONLY);//只写权限
        write(fd,buf,strlen(buf));
        printf("buf:%s\n",buf);
        return 0;
}

//创建read.c文件,作为读取文件
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
int main(void)
{
        char *buf = "hello baby!";
        int fd = open("fifo",O_RDONLY);//只读权限
        read(fd,buf,strlen(buf));
        printf("buf:%s\n",buf);
        return 0;
}

注意:①有名管道的承接文件只能使用mkfifo来创建,不能使用open和creat来创建,他能只能创建普通文件,不能作为承接文件来操作。

           ②使用mkfifo创建的特殊文件fifo,权限的前缀p代表管道文件/特殊文件,文件内容大小显示的0,这就是他的特殊点,不能作为普通文件一样记录内容,只能用来作为承接进程间的通信的媒介。

dhw@dhw-virtual-machine:~$ ls -l
总用量 48
prw-rw-r-- 1 dhw dhw     0  1月 19 18:36 fifo
  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

D.•

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值