通信对象不一样,通信方式不一样
1、管道:一种是无名管道、一种是有名管道
在文件系统中无文件结点
无名管道
通信原理:
管道文件是一个特殊的文件,是由队列来实现的。
在文件IO中创建一个文件或打开一个文件是由open函数来实现的,它不能创建管道文件。只能用pipe函数来创建管道。
文件open——只能创建或打开普通文件,它不能创建管道文件。只能用pipe函数来创建管道。
创建管道——pipe
函数形式:int pipe(int fd[2]);
#include
int pipe(int pipefd[2]);
功能:创建管道,为系统调用:unistd.h
参数:就是得到的文件描述符。可见有两个文件描述符:fd[0]和fd[1],管道有一个读端fd[0]用来读和一个写端fd[1]用来写,这个规矩不能变。
返回值:成功是0,出错是-1
例一:pipe函数使用。
#include
#include
#include
int main()
{
int fd[2];
int ret;
ret=pipe(fd);
if(ret<0)
{
printf("creat pipe failure\n");
return -1;
}
printf("creat pipe sucess fd[0]=%d,fd[1]=%d\n",fd[0],fd[1]);
return 0;
}
执行结果如下:
创建管道成功,fd[0]=3,fd[1]=4.
管道有一个读端fd[0]用来读和一个写端fd[1]用来写
#include
#include
#include
int main()
{
int fd[2];
int ret;
char write_buf[]="hello kiki";
char read_buf[128]={0};
ret=pipe(fd);
if(ret<0)
{
printf("creat pipe failure\n");
return -1;
}
printf("creat pipe sucess fd[0]=%d,fd[1]=%d\n",fd[0],fd[1]);
write(fd[1],write_buf,sizeof(write_buf));
//start read from pipe
read(fd[0],read_buf,128);
printf("read_buf=%s\n",read_buf);
close(fd[0]);
close(fd[1]);
return 0;
}
执行结果如下:
注意:
-管道是创建在内存中的,进程结束,空间释放,管道就不存在了;
-管道中的东西,读完了就删除了;队列——出队以后队列的内容就已经不在了
-如果管道中没有东西可读,则会阻塞。
例2:验证读阻塞
#include
#include
#include
#include
int main()
{
int fd[2];
int ret;
char write_buf[]="hello kiki";
char read_buf[128]={0};
ret=pipe(fd);
if(ret<0)
{
printf("creat pipe failure\n");
return -1;
}
printf("creat pipe sucess fd[0]=%d,fd[1]=%d\n",fd[0],fd[1]);
write(fd[1],write_buf,sizeof(write_buf));
//start read from pipe
read(fd[0],read_buf,128);
printf("read_buf=%s\n",read_buf);
//second read from pipe
memset(read_buf,0,128);
read(fd[0],read_buf,128);
printf("second read after\n ");
close(fd[0]);
close(fd[1]);
return 0;
}
执行结果如下:
例3:验证写阻塞:可以计算出内核开辟的管道有多大。65536
#include
#include
#include
#include
int main()
{
int fd[2];
int ret;
int i=0;
char write_buf[]="hello kiki";
char read_buf[128]={0};
ret=pipe(fd);
if(ret<0)
{
printf("creat pipe failure\n");
return -1;
}
printf("creat pipe sucess fd[0]=%d,fd[1]=%d\n",fd[0],fd[1]);
while(i<6500)
{
write(fd[1],write_buf,sizeof(write_buf));
i++;
}
printf("write pipe end\n");
close(fd[0]);
close(fd[1]);
return 0;
}
执行结果如下:
如果写阻塞,后面的printf语句不会执行,则说明管道写满了
例4:实现进程通信
#include
#include
#include
#include
int main()
{
pid_t pid;
int fd[2];
char process_inter=0;
int ret=pipe(fd);
if(ret<0)
{
printf("creat pipe failure\n");
return -1;
}
printf("creat pipe sucess\n");
pid = fork();
if(pid==0)
{
int i=0;
read(fd[0],&process_inter,1);//if pipe empty sleep
while(process_inter==0);
for(i=0;i<5;i++)
{
printf("this is child process i=%d\n",i);
usleep(100);
}
}
if(pid>0)
{
int i=0;
for(i=0;i<5;i++)
{
printf("this is parent process i=%d\n",i);
usleep(100);
}
process_inter=1;
sleep(3);
write(fd[1],&process_inter,1);
}
while(1);
return 0;
}
执行结果如下:
无名管道的缺点:不能实现不是父子进程(亲缘关系)之间的通信。