进程间通讯:多个进程间数据变换。
通讯方式:信号、管道、信号量、消息队列、共享内存、套接字
这里我要讲的是管道,管道分为半双工通讯、全双工通讯。如果要举例说明的话,半双工通讯就类似自来水管,全双工通讯就类似我们打电话。下面我先用画图解释一下管道的原理:
管道不对数据流向做规定,因此为防止进程A读取自己写入的数据(没有意义)采用半双工通讯。
管道操作如下:
一、有名管道:在文件目录树下有一个文件标识(管道文件),不占据磁盘空间,只有一个inode结点,数据缓存在内存上(有大小
限
制)。有名管道应用于任意两个进程之间数据的单向传递。
优点:可以在任意两进程间完成通讯。
1、创建:命令方式:mkfifo; 函数方式:mkfifo();
打开:open();
写数据:write();
读数据:read();
关闭:close();
2、阻塞运行函数:函数调用以后并不会立即返回,需要等待某些条件的发生才会返回。例如,open()操作管道文件时,阻塞运行的
函数。通俗的来讲就是open函数阻塞运行,当有人读管道才有存在意义。
如果一个进程以只写方式打开一个管道文件,open会阻塞运行,直到有一个进程以只读方式打开管道文件,open才会返回,进程
才会接着执行;
如果一个进程以只读方式打开一个管道文件,open会阻塞运行,直到有一个进程以只写方式打开管道文件,open才会返回,进程
才会接着执行。
read函数也会阻塞运行,直到写端写入数据或者所有的写端都关闭。read()读取数据并且会将内存上的已读数据清空。
二、无名管道:相对于有名管道而言,无名管道在使用时产生,不使用后释放,并且不会在系统上留下任何“痕迹”。
无名管道因其使用前没有任何的提示,所以它只能应用于父子进程之间。因为子进程会完全复制父进程的文件数组。(浅拷贝)
1、创建、打开:int pipe(int da[2]); // fd[0]读;fd[1]写;
2、读:read(fd[0],buff,size);
3、写:write(fd[1],buff,len);
4、关闭:close(fd[0]); close(fd[1]);
注意:管道都是半双工通讯,而无名管道创建后,父进程在fork产生子进程后两个进程分别有一对读写,所以,要在父子进程分别关
闭或写。就是只保留一对读写,分别存在于父子进程。