管道的创建与读写pipe

1、管道的创建

#include <unistd.h>

int pipe(int pipefd[2]);

linux下创建管道可以通过函数pipe来完成。该函数如果调用成功,数组中将包含两个新的文件描述符。

管道两端可分别用描述符fd[0] 以及fd[1]来描述。需要注意的是,管道两端的任务是固定的,一端只能用于读,由描述符fd[0]表示,称其为管道读端;

另一端只能用于写,由描述符fd[1]来表示,称其为管道写端。如果试图从管道写端读数据,或者向管道读端写数据都将导致出错。

管道是一种文件,因此对文件操作的I/O函数都可以用于管道,如read,write等。

管道一旦创建成功,就可以作为一般的文件来使用,对一般文件进行操作的I/O函数也适用于管道文件。

------------------------------------------------------------------------------------------

管道的一般用法是,进程在使用fork函数创建子进程前先创建一个管道,该管道用于在父子进程间通信,然后创建子进程,

之后父进程关闭管道的读端,子进程关闭管道的写端。父进程负责向管道写数据而子进程负责读数据。当然父进程可以关闭管道的写端而子进程关闭管道的读端。

这样管道就可以用于父子进程间的通信,也可以用于兄弟进程间的通信。

2、从管道中读数据

如果某个进程要读取管道中的数据,那么该进程应当关闭fd[1],同时向管道写数据的进程应当关闭fd[0]。因为管道只能用于具有亲缘关系的进程间的通信,在各个程进行通信时,

他们共享文件描述符。在使用前,应及时地关闭不需要的管道的另一端,以避免意外错误的发生。

进程在管道的读端读数据时,如果管道的写端不存在,则读进程认为已经读到了数据的末尾,读函数返回读出的字节数为0;管道的写端如果存在,且请求读取的字节数大于

PIPE_BUF,则返回管道中现有的所有数据;如果请求的字节数不大于PIPE_BUF,则返回管道中现有的所有数据(此时,管道中数据量小于请求的数据量),或者返回请求的

字节数(此时,管道中数据量大于等于请求的数据量)。

注意:PIPE_BUF在/usr/include/linux/limits.h中定义,不同的内核版本可能会有所不同。

3、向管道写数据

如果某进程希望向管道中写入数据,那么该进程应当关闭fd[0]文件描述符,同时管道另一端的进程关闭fd[1]。向管道中写入数据时,linux不保证写入的原子性(原子性是指操作在

任何时候都不能被任何原因所打断,操作要么不做要么就一定完成)。管道缓冲区一有空闲区域,写进程就会试图向管道写入数据。如果读进程不读走管道缓冲区中的数据,那么

写操作将一直被阻塞等待。

在写管道时,如果要求写的字节数小于等于PIPE_BUF,则多个进程对同一管道的写操作不会交错进行。但是,如果有多个进程同时写一个管道,而且某些进程要求写入的字节数超过

PIPE_BUF所能容纳时,则多个写操作的数据可能会交错。

注意:

只有在管道的读端存在时,向管道中写入数据才有意义。否则,向管道写入数据的进程将收到内核传来的SIGPIPE信号。应用程序可以处理也可以忽略该信号,如果忽略该信号或者

从其处理程序返回,则write出错,错误码为EPIPE。

必须在系统调用fork之前调用pipe,否则子进程将不会继承管道的文件描述符。

#include <stdio.h>
#include <unistd.h>
#include <strings.h>
#include <string.h>
#include <stdlib.h>

int main()
{
    char* str = "i am parent";
    char buf[4];
    bzero(buf, sizeof(buf));
    pid_t pid;
    int fd[2];

    pipe(fd);

    pid = fork();
    if(0 == pid)//child read
    {
        sleep(1);//等待父进程向管道写入数据
        printf("i am child, read to read\n");
        close(fd[1]);

        while(read(fd[0], buf, sizeof(buf)-1) > 0)
        {
            //printf("len=%d, %s\n", strlen(buf), buf);
            write(STDOUT_FILENO, buf, strlen(buf));
            bzero(buf, sizeof(buf));
        }

        write(STDOUT_FILENO, "\n", 1);
        close(fd[0]);

        exit(0);

    }
    else//parent write
    {
        printf("i am parent, read to read\n");
        close(fd[0]);

        write(fd[1], str, strlen(str));

        close(fd[1]);

        wait(NULL);//

        exit(0);

    }

}
时间: 2024-08-09 10:36:52

管道的创建与读写pipe的相关文章

四十六、进程间通信——管道的分类与读写

46.1 管道介绍 46.1.1 管道通信 管道是针对于本地计算机的两个进程之间的通信而设计的通信方法,建立管道后,实际获得两个文件描述符:一个用于读取而另一个用于写入 最常见的 IPC 机制,通过 pipe 系统调用 管道是单工的,数据只能向一个方向流动,需要双向通信时,需要建立起两个管道 数据的读出和写入: 一个进程向管道中写的内容被管道另一端的进程读出. 写入的内容每次都添加在管道缓冲区的末尾,并且每次都是从缓冲区的头部读出数据 管道实际上就是建立在内核区域的一块缓存 46.1.2 管道分

linux中用无名管道进行文件的读写

1管道是什么: 水管子大家知道,有两端,在此一端用来读一端用来写,其中一端的输出作为另外一端的输入. 2 函数原型 int pipe(int pipefd[2]);//参数中分别代表的两端 3 例子:管道一端作为写 另外一端作为读 父子进程实现 1 #include <unistd.h> 2 #include <stdio.h> 3 #include <stdlib.h> 4 5 int main() 6 { 7 pid_t pid; 8 int temp; 9 int

C#创建、读写、增加、删除XML操作

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Xml;using System.Collections; namespace CommandXML{    public class cmdXML    { /// <summary>        /// 创建XML文件        /// &

WinForm 创建与读写配置文件

(转自:http://www.cnblogs.com/SkySoot/archive/2012/02/08/2342941.html) 1. 创建 app.config 文件: 右击项目名称,选择“添加”→“添加新建项”,在出现的“添加新项”对话框中,选择“添加应用程序配置文件”:如果项目以前没有配置文件,则默认的文件名称为“app.config”,单击“确定”. 出现在设计器视图中的app.config文件为: <?xml version="1.0" encoding=&quo

net8:文本文件的创建及其读写

原文发布时间为:2008-08-06 -- 来源于本人的百度文章 [由搬家工具导入] using System;using System.Data;using System.Configuration;using System.Collections;using System.Web;using System.Web.Security;using System.Web.UI;using System.Web.UI.WebControls;using System.Web.UI.WebContro

利用管道进行通信

管道简介: 管道是单向的.先进先出的.无结构的.固定大小的字节流,它把一个进程的标准输出和另一个进程的标准输入连接在一起.写进程在管道的尾端写入数据,读进程在管道的首端读出数据.数据读出后将从管道中移走,其它读进程都不能再读到这些数据.管道提供了简单的流控制机制.进程试图读空管道时,在有数据写入管道前,进程将一直阻塞.同样,管道已经满时,进程再试图写管道,在其它进程从管道中移走数据之前,写进程将一直阻塞. 关于管道的代码实例 此程序是关于管道的创建和读写和关闭 #include<unistd.h

管道容量及缓冲区的组成

每个进程都有不同的用户地址空间,任何一个进程的全局变量在 另一个进程中都看不到,所以进程之间要交换数据必须 通过内核,在内核中开辟一块缓冲区,把进程1的数据从用户空间考到内核区,进程2再从内核区把数据考走,内核提供的这种机制叫做进程间通信 (一)管道的外部实现 当我们定义一个管道时,这个管道是由内核管理的一个缓冲区,可以抽象为现实生活中的线路:管道的一端链接一个进程的输出 ,这个进程 会向管道中放入信息:管道的另一端链接一个进程的输出,这个进程取出被放入的信息.当管道被放满时尝试放入信息的进程会

Linux基础篇 进程通信——管道

IPC(InterProcess Communication)进程间通信 每个进程各?自有不同的?用户地址空间,任何?一个进程的全局变量在另?一个进程中都看不到所以进 程之间要交换数据必须通过内核,在内核中开辟?一块缓冲区,进程1把数据从?用户空间拷到内核缓 冲区,进程2再从内核缓冲区把数据读?走,内核提供的这种机制称为进程间通信. linux下进程间通信的几种主要?手段简介: 1 管道(Pipe)及有名管道(named pipe):管道可?用于具有亲缘关系进程间的通信,有名管道克服了管道没有名

liunx 进程间通信总结

         进程间通信 每个进程各有不同的用户地址空间,任何一个进程的全局变量在另一个进程中都看不到. 所以进程之间要交换数据必须通过内核,在内核中开辟一块缓冲区,进程1把数据从用户空间拷到内核缓冲区,进程2再从内核缓冲区把数据读走,内核提供的这种机制称为进程间通信 (IPC,InterProcess Communication) 如图: 1.进程间的通信方式 无名管道( pipe ):管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用.进程的亲缘关系通常是指