管道通信:有名管道(FIFO) 和 无名管道(pipe)

管道通信:

一个进程在管道的尾部写入数据,另一个进程从管道的头部读出数据。管道包括无名管道有名管道两种,前者只能用于父进程和子进程间的通信,后者可用于运行于同一系统中的任意两个进程间的通信。

管道通信特点:
1. 管道通讯是单向的,有固定的读端和写端
2. 数据被进程从管道读出后,在管道中该数据就不存在了。
3. 当进程去读取空管道的时候,进程会阻塞。
4. 当进程往满管道写入数据时,进程会阻塞。
5. 管道容量为64KB(#define PIPE_BUFFERS 16 include/linux/pipe_fs_i.h)

无名管道(pipe):

在Linux系统中,无名管道一旦创建完成后,操作无名管道等同于操作文件。无名管道的读端被视作一个文件;无名管道的写端也被视作一个文件。因此可以使用read,write,close等文件操作函数来访问无名管道。只能用于父进程和子进程间的通信。

有名管道(FIFO):

有名管道又称为FIFO文件(先进先出),因此我们对有名管道的操作也可以采用操作文件的方法,如使用open,read,write等。可用于运行于同一系统中的任意两个进程间的通信。

FIFO文件对比普通文件:
FIFO文件在使用上和普通文件有相似之处,但是也有
不同之处:
1. 读取Fifo文件的进程只能以”RDONLY”方式打开fifo文件。
2. 写Fifo文件的进程只能以”WRONLY”方式打开fifo文件。
3. Fifo文件里面的内容被读取后,就消失了。但是普通文件里面的内容读取后还存在。

管道通信相关函数

  • 创建无名管道

函数原形: int pipe(int pipefd[2]);

函数功能:创建无名管道。

所属头文件:

#include <unistd.h>

返回值:
若成功,返回0;若失败,返回-1.

参数说明:
pipefd[2]:用于返回两个文件描述符,分别指向管道的两端。pipefd[0] 指向的是管道的读端,pipefd[1]指向管道写端。因此,向管道内写和读数据,使用文件操作的函数就可以了,read和write、close函数。

  • 创建有名管道

函数原形:
int mkfifo(const char *pathname, mode_t mode);

函数功能:
创建有名管道,即创建FIFO文件

所属头文件:

#include <sys/types.h>
#include <sys/stat.h>

返回值:
若成功,返回0;若失败,返回-1.

参数说明:
pathname:要创建的fifo文件的路径和文件名
mode:创建文件的访问权限,与文件编程函数的mode相同。

  • 删除有名管道

函数原形:
int unlink(const char *pathname);

函数功能:
删除文件,不仅能删除fifo文件,还能删别的文件。其实,可以使用close关闭管道文件即可

所属头文件:

#include <unistd.h>

返回值:
若成功,返回0;若失败,返回-1.

参数说明:
pathname:要删除的文件的路径和文件名

例程:

1、无名管道编程

/* 创建有名管道,写数据 */
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
//两个独立的进程,一个写进程另一个读进程
//写进程,创建FIFO,写入数据,退出
//读进程,读出数据,显示数据
void main()
{
    int fd;

    mkfifo("./myfifo", 0777);       //创建fifo文件
    fd = open("./myfifo", O_WRONLY);//打开fifo文件
    write(fd, "hello fifo", 11);    //写入数据
    close(fd);//关闭fifo文件        
}

2、有名管道编程 —-读文件

/* 从有名管道中,读数据 */
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
//两个独立的进程,一个写进程另一个读进程
//写进程,创建FIFO,写入数据,退出
//读进程,读出数据,显示数据
void main()
{
    int fd;
    char buf[15];
    fd = open("./myfifo", O_RDONLY);     //打开fifo文件
    read(fd, buf, 11);                   //写入数据
    printf("read result is %s.\n",buf);
    close(fd);                           //关闭fifo文件 
    unlink("./myfifo");                  //删除管道 
}

3、有名管道编程 —-写文件

/* 创建有名管道,写数据 */
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
//两个独立的进程,一个写进程另一个读进程
//写进程,创建FIFO,写入数据,退出
//读进程,读出数据,显示数据
void main()
{
    int fd;

    mkfifo("./myfifo", 0777);       //创建fifo文件
    fd = open("./myfifo", O_WRONLY);//打开fifo文件
    write(fd, "hello fifo", 11);    //写入数据
    close(fd);//关闭fifo文件        
}
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
匿名管道有名管道都是Linux系统中用于进程间通信的机制,它们的主要差异在于命名方式和使用方法。 匿名管道是一种无名的管道,它只能用于在父进程和子进程之间传递数据。匿名管道只能在创建它的进程及其子进程之间使用,其他进程无法访问。匿名管道的创建使用pipe系统调用,创建后可以使用文件描述符进行读写操作。匿名管道的读写是基于先进先出的队列,数据只能单向流动。例如,以下代码演示了如何使用匿名管道在父进程和子进程之间传递数据: ``` #!/bin/bash # 创建匿名管道 pipe=$(mktemp -u) mkfifo $pipe # 在子进程中写入数据 echo "hello from child process" > $pipe # 在父进程中读取数据 read line < $pipe echo "received data: $line" # 清理管道 rm $pipe ``` 有名管道也被称为FIFO管道,它是一种带有名称的管道,可以用于不同进程之间的数据传输。有名管道可以在任意进程中使用,只需要知道管道的名称即可。有名管道的创建使用mkfifo命令,创建后可以使用文件描述符进行读写操作。有名管道的读写也是基于先进先出的队列,数据只能单向流动。例如,以下代码演示了如何使用有名管道在两个进程之间传递数据: ``` #!/bin/bash # 创建有名管道 pipe=/tmp/myfifo mkfifo $pipe # 启动一个进程往管道写入数据 echo "hello from process A" > $pipe & # 读取管道中的数据 read line < $pipe echo "received data: $line" # 清理管道 rm $pipe ``` 总的来说,匿名管道适用于父子进程之间的数据传输,而有名管道适用于任意进程之间的数据传输。在使用管道进行进程间通信时,需要注意管道的读写顺序,否则会导致读取或写入失败。另外,管道的容量是有限的,如果写入的数据超过了管道的容量,会导致写入阻塞。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值