1.IPC
\qquadlinux环境下,进程的地址空间相互独立,每个进程都有各自不同的用户地址空间。任何一个进程的全局变量在另外一个进程中都看不到,所以进程之间不能直接互相访问,进程间要想交换数据只能通过内核,在内核中开辟一块缓冲区,进程1把数据从用户空间拷贝到内核缓冲区,进程2再从内核缓冲区把数据读走,内核提供的这种机制被称为进程间通信(IPC,interprocess communication)。
\qquad在进程间完成数据互换,需要借助操作系统提供的特殊方式,现在常用的有:管道(最简单)、信号(开销最小)、共享映射区(无血缘关系)、本地套接字(最稳定)
2.管道
\qquad管道是一种最基本的IPC机制,作用于有血缘关系的进程之间,进行数据交换。其具有如下的特点:
\qquad管道本质是一种伪文件(实际是内核缓冲区)
\qquad由两个文件描述符引用,一个表示读端,一个表示写端
\qquad规定从管道的写端流入数据,从管道的读端流出数据
\qquad管道的原理:管道通过内核使用环形队列机制,借助内核缓冲区(4k)实现。
3.查看管道默认大小
ulimit -a
结果pipe size (512 bytes, -p) 8
:
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 14488
max locked memory (kbytes, -l) 65536
max memory size (kbytes, -m) unlimited
open files (-n) 1024
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 14488
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
\qquad 8*512b=4k
\quad管道的局限性:
\qquad数据不能自写自读
\qquad数据一旦被读走,便在管道中消失,不能反复读取
\qquad由于管道采用半双工通信方式,因此,数据只能在一个方向上流动。
\qquad只能在有公共祖先的进程间使用管道
4.管道交换数据的例子
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h>int main()
{int fd[2];int ret;pid_t pid;ret = pipe(fd);if(ret==-1){perror("pipe error");exit(1);}pid = fork();if(pid==-1){perror("fork error");exit(1);}else if(pid==0){ //子进程close(fd[1]);char buf[1024];ret = read(fd[0],buf,sizeof(buf));//读到buf里面if(ret==0){printf("读取完成\n");}write(STDERR_FILENO,buf,ret);}else{close(fd[0]);write(fd[1],"hello world\n",strlen("hello world\n"));}return 0;
}