Linux进程间通信——无名管道

Linux进程间通信——无名管道

每个进程各自有不同的用户地址空间,任何一个进程的全局变量在另一个进程中都看不到,所以进程之间要交换数据必须通过内核,在内核中开辟一块缓冲 区,进程1把数据从用户空间拷到内核缓冲区,进程2再从内核缓冲区把数据读走,内核提供的这种机制称为进程间通信(IPC,InterProcess Communication).

pipe.jpg

无名管道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]); 向这个文件读写数据

其实是在读写内核缓冲区.

创建无名管道步骤:

  1. 父进程调用pipe(int pipe_fd[2])函数,创建管道并得到两个文件描述符,分别指向管道的头部和尾部,也就是读端和写端

  2. 父进程调用fork()函数创建子进程,因为fork()函数,子进程拷贝父进程的数据段和代码段,所以子进程也能得到第一步创建的两个文件描述符,且指向同一个管道

  3. 父进程关闭管道的读端,子进程关闭管道的写端

代码:

 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);
    }
}

图解:

blob.png

来自: http://blog.csdn.net/my9074/article/details/42919647

Licensed under CC BY-NC-SA 4.0