无名管道和有名管道的区别

无名管道(pipe)

在文件系统中没有实际的文件与之对应,存在内存里。

特点

1.只能用于亲缘进程间通信。

2.半双工的通信,具有固定的读端和写端。

3.管道是特殊文件,可以使用write、read、close操作,不支持sleep()操作。

无名管道的初始化

int pipefd[2] = {0};//读管道和写管道
int pipe(int pipefd[2]);

 通过无名管道,实现父子进程的通信

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

#define SIZE 128
int main(int argc,char *argv[])
{
        int pipefd[2] = {0};//读端和写端
        int ret = pipe(pipefd);//无名管道的初始化
        if(ret <0)
        {
                perror("pipe");
                return -1;
        }

        pid_t pid = fork();//创建子进程
        if(pid < 0)
        {
                perror("fork");//错误描述
                return -1;
        }
        else if(pid == 0)//子进程
        {
                close(pipefd[0]);//关闭读端
                char buf[SIZE];
                do{
                        fgets(buf,sizeof(buf),stdin);//键盘写入到buf里
                        int ret = write(pipefd[1],buf,sizeof(buf));//通过buf写入到管道中
                        if(ret < 0)
                        {
                                perror("write");
                                break;
                        }
                }while(strncmp(buf,"quit",4) != 0);//“quit”退出

                close(pipefd[1]);//关闭写端
                exit(0);进程退出

        }
        else//父进程
        {
                close(pipefd[1]);//关闭写端
                char buf[SIZE];
                while(1)
                {
                        int ret = read(pipefd[0],buf,sizeof(buf));//读管道中的数据
                        if(ret < 0)
                        {
                                perror("read");
                                break;
                        }
                        else if(ret ==0)//写端关闭,读端退出
                        {
                                printf("write pipe closed\n");
                                break;
                        }

                        printf("buf:%s\n",buf);
                }
                close(pipefd[0]);
                exit(0);

        }


        return 0;
}

注意: 

 1.当管道中没有数据时,读管道堵塞;

 2.当写端关闭时,读管道会立即返回0;

3.当读端关闭,写端写管道时会出现管道破裂,并产生SIGPIPE信号。

有名管道 (fifo)

在文件系统中有实际的文件与之对应(管道文件)

特点 

1.有名管道可以使用互不相关的两个进程互相通信。

2.有名管道可以通过路径名来指出,并且在文件系统中可见。

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

4.有名管道遵循先进先出规则。不支持lseek()操作。

有名管道的初始化

 

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

pathname:管道文件路径

mode:文件权限

通过有名管道实现两个互不相关的进程互相通信 

 1.创建管道文件(myfifo),myfifo.c

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

int main(int argc,char *argv[])
{
        int ret = mkfifo("myfifo",0777);
        if(ret < 0 )
        {
                perror("mkfifo");
                return -1;
        }
        printf("mkfifo success");
        return 0;
}

2.写端写入数据,fifowrite.c

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

#define SIZE 128
int main(int argc,char *argv[])
{
        int fd = open("myfifo",O_WRONLY);
        if(fd < 0)
        {
                perror("open");
                return -1;
        }

        char buf[SIZE];
        do{
            fgets(buf,sizeof(buf),stdin);
            int ret = write(fd,buf,sizeof(buf));
            if(ret < 0)
            {
                perror("write");
                return -1;
            }
        }while(strncmp(buf,"quit",4) != 0);

        close(fd);
        return 0;
}

 3.读端读数据,fiforead.c

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

#define SIZE 128
int main(int argc,char *argv[])
{
        int fd = open("myfifo",O_RDONLY);
        if(fd < 0)
        {
                perror("open");
                return -1;
        }

        char buf[SIZE];

        while(1)
        {
                int ret = read(fd,buf,sizeof(buf));
                if(ret <0)
                {
                        perror("read");
                        break;
                }
                if(ret == 0)
                {
                        printf("fifo write closed\n");
                        break;
                }
                else
                printf("buf:%s\n",buf);
        }
        close(fd);
        return 0;
}

 编译结果

1@buntu:~/day$ gcc fifowrite.c
1@ubuntu:~/day$ ./a.out
hello
I am fifowrite file
   
1@ubuntu:~/day$ gcc fiforead.c
1@ubuntu:~/day$ ./a.out
buf:hello

buf:I am fifowrite file

fifo write closed

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值