进程通信之一 pipe

开题

其实按照开源领域的原则来说,本文是不该产生的。因为进程通信别人整理过无数次了。知识应该重用。但是呢,从本人提高的过程来说,这里算是做个记录吧。

详解

管道是Linux支持的最初Unix IPC形式之一,具有以下特点:

    * 管道是半双工的,数据只能向一个方向流动;需要双方通信时,需要建立起两个管道;
    * 只能用于父子进程或者兄弟进程之间(具有亲缘关系的进程);
    * 单独构成一种独立的文件系统:管道对于管道两端的进程而言,就是一个文件,但它不是普通的文件,它不属于某种文件系统,而是自立门户,单独构成一种文件系统,并且只存在与内存中。
    * 数据的读出和写入:一个进程向管道中写的内容被管道另一端的进程读出。写入的内容每次都添加在管道缓冲区的末尾,并且每次都是从缓冲区的头部读出数据。

示例

/*
 * =====================================================================================
 *
 *       Filename:  pipe.c
 *
 *    Description:  IPC using pipe
 *
 *        Version:  1.0
 *        Created:  2012年02月17日 10时15分01秒
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  chn89 (), chn89@126.com
 *   Organization:  
 *
 * =====================================================================================
 */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#define MAXLINE 80
int main(void)
{
    int n, fd[2];
    pid_t    pid;
    char    line[MAXLINE];

    if (pipe(fd) < 0)
        printf("pipe error");

    if ( (pid = fork()) < 0)
        printf("fork error");

    else if (pid > 0) {        /* parent */
        close(fd[0]);
        write(fd[1], "hello world\n", 12);

    } else {                /* child */
        close(fd[1]);
        n = read(fd[0], line, MAXLINE);
        write(STDOUT_FILENO, line, n);
    }

    exit(0);
}


注意事项

使用管道需要注意以下4种特殊情况(假设都是阻塞I/O操作,没有设置O_NONBLOCK标志):

   1.如果所有指向管道写端的文件描述符都关闭了(管道写端的引用计数等于0),而仍然有进程从管道的读端读数据,那么管道中剩余的数据都被读取后,再次read会返回0,就像读到文件末尾一样。
   2.如果有指向管道写端的文件描述符没关闭(管道写端的引用计数大于0),而持有管道写端的进程也没有向管道中写数据,这时有进程从管道读端读数据,那么管道中剩余的数据都被读取后,再次read会阻塞,直到管道中有数据可读了才读取数据并返回。
   3.如果所有指向管道读端的文件描述符都关闭了(管道读端的引用计数等于 0),这时有进程向管道的写端write,那么该进程会收到信号SIGPIPE,通常会导致进程异常终止。在第 33 章 信号会讲到怎样使SIGPIPE信号不终止进程。
   4.如果有指向管道读端的文件描述符没关闭(管道读端的引用计数大于0),而持有管道读端的进程也没有从管道中读数据,这时有进程向管道写端写数据,那么在管道被写满时再次write会阻塞,直到管道中有空位置了才写入数据并返回。

局限性

    * 只支持单向数据流;
    * 只能用于具有亲缘关系的进程之间;
    * 没有名字;
    * 管道的缓冲区是有限的(管道制存在于内存中,在管道创建时,为缓冲区分配一个页面大小);
    * 管道所传送的是无格式字节流,这就要求管道的读出方和写入方必须事先约定好数据的格式,比如多少字节算作一个消息(或命令、或记录)等等;


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值