Unix下管道实现进程间通信

最近在看Java的NIO的JDK源码时,发现在Selector的实现的底层用到了pipe管道的知识,于是就来学习记录一波。

1.进程间利用管道通信的应用场景

主要是数据传输:一个进程需要将数据发送给另外一个进程;

2. 管道通信:

一个进程在管道的尾部写入数据,另一个进程从管道的头部读出数据。管道包括无名管道有名管道两种,前者只能用于父进程和子进程间的通信,后者可用于运行于同一系统中的任意两个进程间的通信。下面用一个示意图来表示:
Unix下管道实现进程间通信_第1张图片

3. 管道通信的特点

  1. 管道通讯是单向的,先进先出,有固定的读端和写端。
  2. 数据被进程从管道读出后,在管道中该数据就不存在了。
  3. 当进程去读取空管道的时候,进程会阻塞。
  4. 当进程往满管道写数据时,进程会阻塞。
  5. 管道容量为64KB(#define PIPE_BUFFERS 16
    include/linux/pipe_fs_i.h)

4.无名管道

在Linux系统中,无名管道一旦创建完成后,操作无名管道等同于操作文件。无名管道的读端被视作一个文件;无名管道的写端也被视作一个文件。

发送进程利用文件系统的系统调用write(fd[1],buf,size),把buf种的长度为size字符的消息送入管道入口fd[1],接收进程则使用系统调用read(fd[0],buf,size)从管道出口fd[0]出口读出size字符的消息置入buf中。这里,管道按FIFO(先进先出)方式传送消息,且只能单向传送消息(如图)。

利用UNIX提供的系统调用pipe,可建立一条同步通信管道。其格式为:
int fd[2];
pipe(fd)
这里,fd[1]为写入端,fd[0]为读出端。

/*
创建无名管道,用于父子进程间通信,在创建子进程之前创建无名管道
*/
#include 
#include 
#include 
#include 

void main()
{
    pid_t pid = 0;
    int pipefd[2];/定义文件描述符,[0]是读端;[1]是写端。
    char c_buf[10];//缓冲区
    /*创建管道*/
    pipe(pipefd);

    /*创建子进程*/
    pid = fork();

    if(pid > 0)
    {
        /*父进程写入数据*/
        write(pipefd[1], "hello",6);
        wait(NULL);
        close(pipefd[1]);
        exit(0);
    }
    if(pid == 0)
    {
        /*子进程读取数据*/
        read(pipefd[0], c_buf, 6); 
        printf( "child read %s\n", c_buf);
        close(pipefd[0]);
        exit(0);
    }   
}

运行结果如图:
Unix下管道实现进程间通信_第2张图片

你可能感兴趣的:(Java基础)