概念:
管道通信分为有名管道和无名管道。从本质上说,管道也是一种文件,但它又和一般的文件有所不同,管道可以克服使用文件进行通信的俩个问题:
1)限制管道的大小。实际上,管道是一个固定大小的缓冲区。在Linux中,该缓冲区的大小为一页,即4K字节,使它的大小不像文件那样不加检验的增长。使用单个固定缓冲区也会带来问题,比如在写管道时可能变满,当这种情况发生时,随后对管道的write()调用将默认的被阻塞,等待某些数据被读取,以便腾出足够的空间供write()调用写。
2)读取进程也可能工作的比写进程快。当送一当前进程数据已被读取时,管道变空。当这种情况发生时,一个随后的read()调用将被阻塞,等待某些数据被写入,这解决了read()调用返回文件结束的问题
注:从管道读数据是一次性操作,数据一旦被读,它就从管道中被抛弃,释放空间以便写更多的数据。
无名管道,父子进程间的通讯
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
int main(){
int pid;
int fd[2];
char buf2[1024] = "hello world!";
if(pipe(fd) < 0){ //创建管道,fd[0]读,fd[1]写
perror("create pipe error!\n");
exit(1);
}
pid = fork();
if(pid == -1){
perror("fork error!\n");
exit(1);
}
if(pid == 0){
while(1){
memset(buf2,0,sizeof(buf2)); //先把buf2里的内容清空,再读进buf2
read(fd[0],buf2,12);
printf("read:%s\n",buf2);
}
}else if(pid > 0){
while(1){
scanf("%s",buf2);
write(fd[1],buf2,strlen(buf2));
}
}
return 0;
}
有名管道 父子进程间通信
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(){
int pid;
char buf2[1024] = "hello world!";
char *path = "/home/ben/c.d/fifo"; //可随意命名
if(mkfifo(path,0644) < 0){ //mkfifo为创建一个自己命名的管道
perror("make fifo fail!"); //创建的管道如果存在,只提示不退出。
}
pid = fork();
if(pid == -1){
perror("fork error!\n");
exit(1);
}
if(pid == 0){
int fd = open(path,O_RDONLY);
while(1){
memset(buf2,0,sizeof(buf2));
read(fd,buf2,12);
printf("read:%s\n",buf2);
}
}else if(pid > 0){
int fd = open(path,O_WRONLY);
while(1){
scanf("%s",buf2);
write(fd,buf2,strlen(buf2));
}
}
return 0;
}