文章目录提示:进程在运行时总是独享其内存镜像,进程间的通讯一般借助管道来完成
- 前言
- 一、pipe
- 1. 内容详解
- 2. 示例代码
- 二、fifo
- 1. 内容详解
- 2. 示例代码
- 总结
前言
应用程序在运行时所产生的进程,在操作系统的加持下都是独享其整个虚拟内存镜像的,这里的独享举例:
在32位的操作系统下,应用程序运行时候的进程,在其运行周期的时间片上,总是独享CPU和4G的内存空间,一般来说4G中的3G为应用程序使用,剩余的1G是交给操作系统内核来使用的。两个不同的进程,其3G的虚拟内存空间是完全独立的,不能直接共享。
在进程独享虚拟内存的前提下,进程间的通讯,也就是交换数据,就需要通过操作系统内核内存或者文件系统(外部磁盘存储介质)来实现。
在 linux 系统下,提供了 pipe 匿名管道的方式借助系统内核内存用于有父子或兄弟关系的进程间通讯,以及 fifo 管道的方式借助文件系统进行通讯。
一、pipe 1. 内容详解
pipe 的管道文件主要用于有直系关系的进程间通讯,比如:父子进程或兄弟进程,主要依靠 pipe(2) 函数,其原型为:
int pipe(int pipefd[2]);
#include二、fifo 1. 内容详解#include #include #include #include #include int main(void) { int fd[2]; // fd[0] is read end of pipe, fd[1] is write end of pipe pid_t pid; // for child pid char *msg = "father process message"; char buf[128]; if (pipe(fd) == -1) printf("Error: pipe failedn"); pid = fork(); // create new child process if (pid == -1) printf("Error: fork failedn"); if (pid == 0) { // child process printf("child process startedn"); read(fd[0], buf, 128); printf("child process get a message: %sn", buf); printf("child process deadn"); exit(0); } else { printf("father process startedn"); write(fd[1], msg, strlen(msg)); wait(NULL); } printf("father process finishedn"); return 0; }
fifo 的管道文件是独立于进程的,用于任意进程间的通讯,主要依靠 mkfifo(3) 函数,其原型为:
int mkfifo(const char *pathname, mode_t mode);
测试代码分为三个部分:
(1)管道文件创建代码
(2)通讯数据写入代码
(3)通讯数据读出代码
三部分代码分别编译之后,先由管道创建程序生成管道文件,至此管道创建程序就不再需要了。
数据写入程序与数据读出程序同时运行时,才能正常的完成通讯并将通讯代码写在屏幕上。如果只打开数据写入/读出代码,都是没办法运行的,因为两方面:
一来是此时的 fifo 文件写入端和读出段都需要打开才能够成功传输数据。
二来是目前的 fifo 配置写入和读出均采用阻塞等待的方式在运行。
(1)管道文件的创建:
#include#include #include int main(int argc, char *argv[]) { int fd; fd = mkfifo(argv[1], 0644); if (fd == -1) printf("mkfifo failedn"); else printf("create fifo file name %sn", argv[1]); return 0; }
(2)通讯数据写入代码
#include#include #include #include int main(int argc, char *argv[]) { char *msg = "pwrite msg"; int size = 0; int fd = open(argv[1], O_WRONLY); if (fd == -1) { printf("open errorn"); return 0; } size = write(fd, msg, strlen(msg)); printf("write %d bytes to fifo filen", size); close(fd); return 0; }
(3)通讯数据读出代码
#include#include #include #include int main(int argc, char *argv[]) { char buf[1024] = {0}; int size = 0; int fd = open(argv[1], O_RDONLY); if (fd == -1) { printf("open errorn"); return 0; } size = read(fd, buf, 1024); printf("read %d bytesn", size); printf("%sn", buf); close(fd); return 0; }
总结
- pipe 和 fifo 的区别在于:pipe提供了匿名管道,自然不会挂载与文件系统,必须有”父子/兄弟”关系的进程才能够生成并进行通讯。fifo提供了和一般文件类似的文件名,将会被挂载至文件系统,可以在任意进程间进行通讯。
- 管道文件与普通文件的区别在于:一般情况下管道文件 读/写 两端必须都是打开的状态,才会用于读写操作,基本的读写操作都是阻塞状态。普通文件 读/写 是完全独立的,可以在任意时间操作。



