目录
一、进程间通信
操作系统中的各个进程独立运行于内存空间中,并且有严格的机制组织进程间的非法访问。进程间通信是操作系统中重要的概念。比如windows系统中的剪贴板,就可以请送从一个程序复制信息到另一个毫无关联的程序中。
进程间通信(Inter-Process-Communication,IPC)的实现方式多种多样。原则上,任何跨进程的数据交换都属于进程间通信。除了传统意义上的消息传递、管道等,还可以使用类似文件共享、公共信息机制等简单方法实现对性能不高的进程通信。
二、管道(Pipe)
管道是操作系统中常见的一种进程间通信,它适用于所有的POSIX系统以及Windows系列产品。Pipe这个词很形象的描述了通信双方的行为,即进程A与进程B。
- 分立管道的两边,进行数据的通信
- 管道是单向的,如果向用一个进程读写数据,则需要建立两个管道
- 管道有容量限制。当pipe满时,写操作将阻塞,反之,读操作将阻塞
三、范例
#include <sys/types.h>
#include <sys/wait.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
int main(int argc,char *argv[])
{
int pipe_fd[2];
pid_t child_pid; // 分配进程ID
char pipe_buf;
memset(pipe_fd,0,sizeof(int)*2); // 赋值
if(pipe(pipe_fd) == -1) { // 通过pipe接口打开管道,pipe[0]和pipe[1]分别表示管道的读、写端
/* 出错处理 */
return -1;
}
child_pid = fork(); // fork一个子进程
if(child_pid == -1) {
/* 出错处理 */
return -1;
}
/* 子进程中的操作 */
if(child_pid == 0) {
close(pipe_fd[1]); // 关闭写端,因为子进程负责读取
while(read(pipe_fd[0],&pipe_buf,1) > 0) // 从管道中读取一个字符
write(STDOUT_FILENO,&pipe_buf,1); // 读取成功,输出
close(pipe_fd[0]); // 关闭读取端
return 0;
}else { /* 父进程中的操作 */
close(pipe_fd[0]); // 和子进程相对应,关闭读取端
write(pipe_fd[1],"H",1); // 写入一个字符 “H”
printf("\n");
close(pipe_fd[1]); // 关闭写入端
wait(NULL);
return 0;
}
}
这个例子的结果就是父进程向管道中写入一个“H”字符,然后子进程读取后输出,从中可以学到:
- Linux提供pipe接口来打开一个管道。函数原型如下:
int pipe(int pipefd[2],int flags);
- 根据fork的特性,当child_pid等于0时,代表的是子进程;否则,是父进程。
- 示例中因为父子进程间的特殊关系可是的两者共享管道文件描述符(即变量pipe_fd)成为可能。如果两者没有关系,则“无法实现”。