每个进程各自有不同的用户地址空间,任何一个进程的全局变量在另一个进程中都看不到,所以进程之间要交换数据必须通过内核,在内核中开辟一块缓冲 区,进程1把数据从用户空间拷到内核缓冲区,进程2再从内核缓冲区把数据读走,内核提供的这种机制称为进程间通信(IPC,InterProcess Communication).
无名管道PIPE只适用于父子进程间的通信,还有一种叫做有名管道FIFO.
PIPE是Linux进程间通信方法之一,它是一个单向通道,先进先出,管道的尾端为写端,描述符pipe_fd[1] . 头部为读端,描述符为pipe_fd[0](注意,强制规定).
主要函数:
1
| int pipe(int pipe_fd[2])
|
调用pipe函数在内核中开辟一块缓冲区(称为管道)用于单向通信,它有一个读端一个写端,然后通过filedes参数传给用户程序两个文件描述符,filedes[0]指
向PIPE的读端,filedes[1]指向PIPE的写端。所以在用户程序看起来就像一个打开的文件,通过read(filedes[0]);或者write(filedes[1]); 向这个文件读写数据
其实是在读写内核缓冲区.
创建无名管道步骤:
父进程调用pipe(int pipe_fd[2])函数,创建管道并得到两个文件描述符,分别指向管道的头部和尾部,也就是读端和写端
父进程调用fork()函数创建子进程,因为fork()函数,子进程拷贝父进程的数据段和代码段,所以子进程也能得到第一步创建的两个文件描述符,且指向同一个管道
父进程关闭管道的读端,子进程关闭管道的写端
代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
| #include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/wait.h>
#include<string.h>
int main()
{
char buf[20];
pid_t pid;
int pipe_fd[2];
pipe(pipe_fd); //创建管道
if ((pid = fork()) < 0) //fork子进程
{
perror("fork error");
exit(-1);
} else if (pid == 0) //子进程中
{
close(pipe_fd[1]); //关闭写端
sleep(1);
read(pipe_fd[0],buf,sizeof(buf));
printf("%s",buf);
close(pipe_fd[0]); //关闭读端
exit(0); //正常退出
} else //父进程中
{
close(pipe_fd[0]); //关闭读端
write(pipe_fd[1],"hello world",strlen("hello world"));
close(pipe_fd[1]); //关闭写端
waitpid(pid,NULL,0); //等待子进程结束或中断,参数1为欲等待的子进程的标识码,参数2为
//子进程结束的状态值一般为NULL,参数3为等待何种子进程,为0时表示等待进程组识别码
//与目前进程相同的任务子进程
exit(0);
}
}
|
图解:
来自: http://blog.csdn.net/my9074/article/details/42919647