管道分类:
管道分为无名管道和命名管道这两种。
管道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;
}
运行结果:
当我们去运行读取的程序,会一直阻塞,等待写的程序运行。