☆管道说明:
为什么需要建立管道:进程与进程在应用层里面不能直接进行信息交互,必须通过内核来进行通信。
管道的作用:创建一个管道作为进程间信息交互的媒介,所以进程A就可以在管道中写入数据,进程B在从管道中读取数据,这样就可以实现进程A与进程B之间的通信。
无名管道与有名管道异同点:
相同点:
①都是半双工通信,只提供单向通信。比如两个进程都能访问这个管道里的内容,如果进程A往管道内写东西,那么进程B 就只能读取管道的内容;
②管道是基于字节流来通信的;
③依赖于文件系统,它的生命周期随进程的结束而结束;
④其本身自带同步互斥效果。不同点:
无名管道:①只适用于带有亲缘关系的进程,比如父子进程;如果进程间没有任何关系,就不能使用无名管道。
②只能实现一个进程写另一个进程读,而如果需要两者同时进行时,就得重新打开一个管道。
有名管道:①可以实现没有任何亲缘关系的进程间的通信,因为有名管道在使用前必须创建一个特殊文件名(mkfifo)来承接进程间的读和写;
②可以实现进程A写,进程B读,也可以实现进程A读,进程B写,无需重新打开新的管道。
☆无名管道(pipe)
返回值:打开管道成功,返回0,打开失败,返回-1;
说明:fd[2]因为有读端和写端两个进程,所以有两个文件描述符,fd[0]为读端,fd[1]为写端,定义好文件描述符后,就使用pipe函数打开管道。
注意:一定要在调用fork之前打开管道,因为管道是属于父子进程共享管道。
妙招:fdp[0],0的形状像嘴巴,嘴巴就用来读,所以为读端;fd[1],1的形状像一直笔,笔用来写,所以为写端。
#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <stdio.h> #include <unistd.h> #include <string.h> int main() { int fd[2];//读端 写端 char *buf = "gogogogogogogogo"; pipe(fd);//打开管道 printf("fd[0]=%d\n",fd[0]);//fd=3 printf("fd[1]=%d\n",fd[1]);//fd=4 int pid = fork(); if(pid > 0){ printf("father pid = %d\n",getpid());//父进程 close(fd[0]);//写之前需关闭读端 write(fd[1],buf,strlen(buf));//写端 写入数据 close(fd[1]);//写入数据后关闭写端 }else if(pid == 0){ printf("child pid = %d\n",getpid());//子进程 close(fd[1]);//读之前须关闭写端 read(fd[0],buf,strlen(buf));//读端,读取数据 printf("buf:%s\n",buf);//打印读取到的内容 close(fd[0]);//读取数据后关闭读端 } return 0; }
☆有名管道(fifo)
返回值:特殊文件创建成功,mkfifo返回0,创建失败,mkfifo返回-1。
说明:① 在使用有名管道之前,使用mkfifo函数创建一个特殊文件来承接进程的读和写,可以先在命令行中先创建这个文件,也可以在编辑代码的时候创建;
if(mkfifo("fifo",0600) == 0){ printf("mkfifo success!\n"); //代码中直接使用mkfifo创建承接文件fifo
② 在编译时,如果只运行read.c文件,不会有内容出现,需要同事编译write.c文件,才能编译出文件内容;
③ 在read.c文件中,对“fifo”文件的权限只需可读即可“O_RDONLY”,在write.c文件中,对‘fifo’文件的权限只需要可读即可“O_WRONLY”。
//先在命令行中使用mkfifo函数创建一个名为fifo的特殊文件 dhw@dhw-virtual-machine:~$ mkfifo fifo //创建write.c文件,作为写入文件 #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <stdio.h> #include <string.h> int main() { char *buf = "hello baby!"; int fd = open("fifo",O_WRONLY);//只写权限 write(fd,buf,strlen(buf)); printf("buf:%s\n",buf); return 0; } //创建read.c文件,作为读取文件 #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <stdio.h> #include <string.h> int main(void) { char *buf = "hello baby!"; int fd = open("fifo",O_RDONLY);//只读权限 read(fd,buf,strlen(buf)); printf("buf:%s\n",buf); return 0; }
注意:①有名管道的承接文件只能使用mkfifo来创建,不能使用open和creat来创建,他能只能创建普通文件,不能作为承接文件来操作。
②使用mkfifo创建的特殊文件fifo,权限的前缀p代表管道文件/特殊文件,文件内容大小显示的0,这就是他的特殊点,不能作为普通文件一样记录内容,只能用来作为承接进程间的通信的媒介。
dhw@dhw-virtual-machine:~$ ls -l 总用量 48 prw-rw-r-- 1 dhw dhw 0 1月 19 18:36 fifo