进程间通信方式之管道
管道:支持单工模型,数据流只能单向流动,如果通信需要交互,可以通过建立两个管道的方式创建通信;
匿名管道:首先只能用于本地进程之间的通信,不支持网络间进程的通信;其次,匿名管道只能用于父子进程以及具有亲缘关系的进程;
这里提供一个用于管道的程序:
平台是Linux 3.10.0内核
#include<stdioh>
#include<stdlib.h>
#include<string.h>
int main(){
int fd[2];
pipe(fd);
char in[] = "Hello Pipe";
write(fd[1],in,sizeof(in));
printf("write:%s\n",in);
char out[sizeof(in)] = {0};
ssize_t n = read(fd[0],out,sizoef(out));
close(fd[0]);
close(fd[1]);
}
解释一下上面的程序:pipe(int *fd) pipe接收一个长度为2的数组,并且将fd[1]作为写入段;fd[0]作为读取端;write()函数用于将数据写入管道的写入端,然后再fd[0]使用read函数读取内容,并进行打印;这个函数的功能比较简单,但是可以体现pipe单向数据流的特点;
整理一下今天学过的几个函数:
fifocreate.c
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
int main(int argc,char **argc){
int c,mode=0644;
while((c = getopt(argc,argv,"t:"))! = -1){
switch(c){
case 't':
mode = strtol(optarg,NULL,8);
break;
}
}
if(optind != argc -1){
printf("usage:%s [-t <mode>] <pathname>\n",argv[0]);
return 1;
}
if(-1 == mkfifo(argv[optind],mode){
perror("mkfifo error");
return 1;
}
}
这个程序的主要作用是用来创建一个管道文件,使用的格式:./fifocreate -t 0744 /tmp/test 这样就会在/tmp目录底下存在一个test文件,使用file /tmp/test 得到的信息:/tmp/test:fifo(name pipe),可以表明这是一个管道文件;
fifowrite.c
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<fcntl.h>
int main(){
int fd = open("/tmp/test",O_WRONLY);
if( -1 == fd ){
perror("open error");
return 1;
}
char str[]="Hello pipe";
fcnl(fd,F_SETEL,O_NONBLOCK);
write(fd,str,sizeof(str));
printf("write:%s\n",str);
}
这个程序的主要功能是利用创建的管道文件/tmp/test写入数据,同时还需要一个函数:
fiforead.c
#include<stdio.h>
#include<unistd.h>
#include<fcntl.h>
int main(){
int fd = open("/tmp/test",O_RDONLY);
if(-1 ==fd){
perror("open error");
return 1;
}
char buf[BUFSIZ];
bzero(buf,BUFSIZE);
fcntl(fd,F_SETEL,O_NONBLOCK);
read(fd,buf,BUFSIZE);
printf("read:%s\n",buf);
}
这个程序中的BUFSIZ是一个宏定义,已经包含在头文件中;fiforead程序需要和fifowrite函数需要同时运行,否则就会进入阻塞状态;bzero()函数和memset()函数都是用来清空数组的;