1.IPC
\qquad
linux环境下,进程的地址空间相互独立,每个进程都有各自不同的用户地址空间。任何一个进程的全局变量在另外一个进程中都看不到,所以进程之间不能直接互相访问,进程间要想交换数据只能通过内核,在内核中开辟一块缓冲区,进程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;
}