Linux进程间通信之管道

管道分类:

管道分为无名管道命名管道这两种。
管道pipe(无名管道):管道是一种半双工的通信方式,同一时刻数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。
命名管道FIFO:有名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信。
单工通信:是指消息只能单方向传输的工作方式。例如遥控、遥测(一部分),就是单工通信方式。单工通信信道是单向信道,发送端和接收端的身份是固定的,发送端只能发送信息,不能接收信息;接收端只能接收信息,不能发送信息,数据信号仅从一端传送到另一端,即信息流是单方向的。
半双工:所谓半双工就是指一个时间段内只有一个动作发生,举个简单例子,一条窄窄的马路,同时只能有一辆车通过,当目前有两辆车对开,这种情况下就只能一辆先过,等到头儿后另一辆再开。
全双工:是指在发送数据的同时也能够接收数据,两者同步进行,这好像我们平时打电话一样,说话的同时也能够听到对方的声音。

1.无名管道

int pipe(int pipefd[2])  //成功返回0,失败返回负一,并设置一个error

函数调用成功返回r/w两个文件描述符。无需open,但需手动close。规定:fd[0] → r; fd[1] → w,就像0对应标准输入,1对应标准输出一样。向管道文件读写数据其实是在读写内核缓冲区。(0-1对应读-写,这样方便记忆)
特点:
1.半双工,一端读时,另一端只能写。
2.只能用于具有亲缘关系的进程,也就是用于fork。
3.可以看成一个特殊的文件,只存在于内存种。也可以用read write函数对其进行操作,但是0是读端,1是写端。
例:
父亲去读,孩子去写。

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

int main()
{

        int pipefd[2];
        char num[128]={'\0'};
        int ret;
        ret = pipe(pipefd);
        if(ret==-1){
                printf("pipe is fail\n");
                perror("pipie:");
        }
        if(fork()>0){
                wait(NULL);
                printf("this is father\n");
                close(pipefd[1]);
                read(pipefd[0],num,sizeof(num));
                printf("read from child:%s\n",num);
                printf("read over\n");
        }else{
                printf("this is child\n");
                close(pipefd[0]);
                write(pipefd[1],"chen wen hao hen shuai",strlen("chen wen hao hen shuai"));
                printf("write over\n");
                exit(0);


        }

        return 0;
}

在这里插入图片描述

2.命名管道

和无名管道的主要区别在于,命名管道有一个名字,命名管道的名字对应于一个磁盘索引节点,有了这个文件名,任何进程有相应的权限都可以对它进行访问
而无名管道却不同,进程只能访问自己或祖先创建的管道,而不能访任意访问已经存在的管道——因为没有名字。

int mkfifo(const char *pathname, mode_t mode);//创建**一个管道**来用于进程通信。成功返回0.失败返回-1,并设置一个error。

pathname:文件名,若文件名以及存在则会出错。
mode:权限 如0600就是可读可写。

读进程代码

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


int main()
{
        char buf[128]={'\0'};
        int fd;
        if(mkfifo("./fail",0600)==-1&&!errno==EEXIST){
                printf("mkfifo fail\n");
                perror("mkfifo");
        }else{
                printf("mafifo success\n");
        }
        fd = open("./fail",O_RDONLY);
        int n_read = read(fd,buf,128);
        printf("read buf:%s   read size:%d\n",buf,n_read);
        close(fd);
        return 0;
}

写进程代码:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
int main()
{
        int fd;
        int ret;
        ret = mkfifo("./fail",0600);
                if(mkfifo("./fail",0600)==-1&&!errno==EEXIST){
                printf("mkfifo fail\n");
                perror("mkfifo");
        }else{
                printf("mafifo success\n");
        }

        fd = open("./fail",O_WRONLY);
        int n_write = write(fd,"chen wen hao hen shuai",strlen("chen wen hao hen shuai"));
        printf("write over,write sizeof:%d\n",n_write);
        close(fd);
        return 0;
}

运行结果:

当我们去运行读取的程序,会一直阻塞,等待写的程序运行。在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值