无名管道与有名管道(FIFO)的应用

1、无名管道

1)、特点:

只能用于具有亲缘关系的进程之间的通信

半双工的通信模式,具有固定的读端和写端

管道可以看成是一种特殊的文件,对于它的读写可以使用文件IO如read、write函数。

#include <unistd.h>

int pipe(int pipefd[2]);  //创建管道,得到管道的读端fd[0]和写端fd[1]

参数:

    pipefd ---- 存放读写文件描述符的数组首地址

返回值:

    成功: 0

    失败: -1, 并设置errno

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>

int main(int argc, char *argv[])
{ 
    pid_t pid;
    char buf[100];
    int ret;
    int fd[2];
    if (0 > pipe(fd))
    {
        perror("pipe");
        return -1;
    }
    printf("fd: %d %d\n", fd[0], fd[1]);

    if (0 > (pid = fork()))
    {
        perror("fork");
        return -1;
    }
    else if (0 == pid)  //child:write
    {
        close(fd[0]);
        while (1)
        {
            printf("Child input: ");
            fgets(buf, sizeof(buf), stdin);
            if (0 > write(fd[1], buf, sizeof(buf)))
            {
                perror("write");
                break;
            }
            if (strncmp(buf, "quit", 4) == 0)
                break;
        }
        close(fd[1]);
    }
    else                                       //parent: read
    {
        close(fd[1]);
        while (1)
        {
            ret = read(fd[0], buf, sizeof(buf));
            if (ret < 0)
            {
                perror("read");
                break;
            }
            else if (0 == ret)
            {
                printf("read end!\n");
                break;
            }
            else
                printf("Parent recv: %s", buf);
        }
        close(fd[0]);
    }

    return 0;
} 

2、有名管道FIFO

无名管道只能用于具有亲缘关系的进程之间,这就限制了无名管道的使用范围

有名管道可以使互不相关的两个进程互相通信。有名管道可以通过路径名来指出,并且在文件系统中可见

进程通过文件IO来操作有名管道

有名管道遵循先进先出规则

不支持如lseek() 操作

有名管道的内容保存在内存中

#include <sys/types.h>

#include <sys/stat.h>

int mkfifo(const char *pathname, mode_t mode);

参数:

    pathname --- 路径 + 名字

    mode     --- 权限,一般0664

返回值:

    成功: 0

    失败: -1, 并设置errno

使用: open close  read  write

有名管道的创建(mkfifo):

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

int main(int argc, char *argv[])
{ 
    if (0 > mkfifo("myfifo", 0664))
    {
        perror("mkfifo");
        return -1;
    }


    return 0;
} 

有名管道的读(read):

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main(int argc, char *argv[])
{ 
    int fd = open("myfifo", O_RDONLY);
    if (fd < 0)
    {
        perror("open");
        return -1;
    }
    
    char buf[100];
    int ret;
  while (1)
    {
        ret = read(fd, buf, sizeof(buf));
        if (ret < 0)
        {
            perror("read");
            break;
        }
        else if (0 == ret)
        {
            printf("read end!\n");
            break;
        }
        printf("recv: %s\n", buf);
    }

   close(fd);

    return 0;
} 

有名管道的写(write):

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>

int main(int argc, char *argv[])
{ 
    int fd = open("myfifo", O_WRONLY);
    if (fd < 0)
    {
        perror("open");
        return -1;
    }
    
    char buf[100];
    int ret;
    while (1)
    {
        printf("Input: ");
        fgets(buf, sizeof(buf), stdin);
        ret = write(fd, buf, sizeof(buf));
        if (ret < 0)
        {
            perror("write");
            break;
        }
        if (strncmp(buf, "quit", 4) == 0)
            break;
    }

    close(fd);

    return 0;
} 

==总结==

* 管道只有在读写端存在时才有意义

* 写端存在时,当管道中有数据时,读端可以读到数据,没有数据时,读端阻塞。但是写端关闭时,读端会把管道中的数据都读走后返回0

* 当读端存在时但不读取数据,写端把管道缓冲区写满后会阻塞,直到读端读走数据就可以继续写入

* 当读端关闭时,写端再向管道中写入,会出现管道破裂的信号(SIGPIPE)导致进程结束

mkfifo  +文件名        (管道的创建)

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

এ᭄星辰

混口饭吃。。。。。

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

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

打赏作者

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

抵扣说明:

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

余额充值