IPC-管道通信

管道(PIPE)



管道是一种最基本的IPC机制,由pipe函数在内核中开辟一块缓冲区(称为管道)用于通信,所以管道在用户程序看起来就像一个打开的文件,通过read(filedes[0]);或者write(filedes[1]);

int pipe(int filedes[2]);

参数:filedes参数传给用户程序两个文件描述符表。filedes[0]指向管道的读端,filedes[1]指向管道的
写端

返回值:成功返回0,失败返回-1

int fseek(FILE *stream, long offset, int fromwhere);

stream:将指向以fromwhere为基准

offset:偏移offset(指针偏移量)个字节的位置

返回值:

失败:(比如offset超过文件自身大小),则不改变stream指向的位置,函数返回一个非0值。

成功:stream将指向fromwhere,偏移量offset个字节的位置。

父子进程通信的步骤:

1.父进程创建管道,开辟管道,得到两个文件描述符指向管道的两端
2.父进程fork创建出子进程,那么子进程也有两个文件描述符指向同一管道
3.父进程关闭fd[0],子进程关闭fd[1]。父进程可以往管道里写,子进程可以往管道里读,管道是环形队列实现的,数据从写端流入,读端流出,这就实现了进程间通信。

管道内部的实现机制:

实际上管道没有单独的实现数据结构 ,他利用文件在Linux中,而是借助文件系统的file结构和VFS文件索引节点inode,通过将两个 file 结构指向同一个临时的VFS 索引节点,而这个 VFS 索引节点又指向一个物理页面而实现的。有两个file数据结构,但它们定义文件操作例程地址是不同的,其中一个是向管道中写入数据的例程地址,而另一个是从管道中读出数据的例程地址。这样,用户程序的系统调用仍然是通常的文件操作,而内核却利用这种抽象机制实现了管道这一特殊操作。

测试管道容量

测试原理:读端不读,写端一直写

#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
#include<error.h>
#include<string.h>
#include<sys/wait.h>

int get_pipe_size(FILE* fd)
{
    fseek(fd,0,SEEK_SET);
    int start = ftell(fd);
    fseek(fd,0,SEEK_END);
    int end = ftell(fd);
    return end - start;
}

int main()
{
    int _pipe[2];
    int ret = pipe(_pipe);
    if(ret == -1)
    {
    //    printf("create pipe error ,error code is:%d\n",error);
        return 1;
    }

    pid_t id = fork();
    if(id <0)
    {
        printf("fork error");
        return 2;
    }
    else if(id == 0)  //child 关闭读端
    {
        close(_pipe[0]);
        int i =0;
        char* _msg = NULL;

        //the writer keep writing
        while(1)
        {
            _msg = "r";
            write(_pipe[1],_msg,strlen(_msg));  //一直写
            printf("%d\n",i);
            i++;
        }
        printf("write over...\n");
    }

    else
    {
        //father
        close(_pipe[1]);//关闭写端
        char _msg[100];
        int j =0;
        sleep(5);
        int status = 0;
        while(1)
        {
            status = 0;
            memset(_msg,‘\0‘,sizeof(_msg));
            printf("%s:code id:%d\n",_msg,ret);

        }
        if(waitpid(id,&status,0)<0)
        {
            return 3;
        }
        printf("status:%d\n",(status)&0xff);
    }
    return 0;
}

测试结果:大约64k

时间: 2024-11-05 15:56:37

IPC-管道通信的相关文章

Linux下的进程通信方式(IPC)——管道通信

Unix IPC: 管道.命名管道(FIFO)      管道 1.概念 管道是单向的(半双工).先进先出.无结构的字节流,它把一个进程的输出和另一个进程的输入连接在一起. 写进程在管道的尾端写入数据,读进程在管道的首端读出数据.数据读出后将从管道中移走,其它读进程都不能再读到这些数据. 管道提供了简单的流控制机制.进程试图读一个空管道时,在数据写入管道前,进程将一直阻塞.同样,管道已经满时,进程再试图写管道,在其它进程从管道中读走数据之前,写进程将一直阻塞. 2.管道的特点 (1)单向数据通信

go语言快速入门 IPC之管道通信 8

熟悉Unix/C编程的应该对IPC也非常的熟悉,多进程之间的通信主要的手段有管道/信号量/共享内存/Socket等,而管道作为父子进程间进行少量数据传递的有效手段也得到了广泛的应用,在这篇文章中我们来看一下go语言中如何使用管道进行进程进行通信. 管道的使用 在linux下,管道被非常广泛地使用,一般在编程中我们实现了popen等的应用即可提供管道功能.而在命令行中使用地也非常多,|就是最为典型的管道的应用例子.shell会为|符号两侧的命令各创建一个脚本,将左侧的输出管道与右侧的输入管道进行连

管道通信,王明学learn

管道通信 一.通讯目的 1.数据传输 一个进程需要将数据发送给另一个进程. 2.资源共享 多个进程之间共享同样的资源. 3.通知事件 一个进程需要向另一个/组进程发送消息,通知它们发生了某事件. 4.进程控制 有些进程希望完全控制另一个进程的执行(如Debug进程),此时控制进程希望能够拦截另一个进程的所有操作,并能够及时知道它的状态改变. 二.通讯发展 Linux进程间通信(IPC:interprocesscommunication)由以下几部分发展而来: 1.UNIX进程间通信 2.基于Sy

IPC进程通信

这两天学习的东西有点多,感觉完全应付不过来了 ,一直在消化这几天学习的东西所以2号.3号.4号的学习内容没有及时总结,在此表示深深的愧疚,今天把这些天学习的知识点汇总一下. 主要学习了IPC进程间通信,目前我所理解的IPC主要包括管道.共享内存.信号量. 总结IPC前先复习一下多进程: 一.进程创建: 1.system函数 通过调用shell程序/bin/sh –c来执行string所指定的命令,该函数在内部是通过调用execve("/bin/sh",..)函数来实现的.通过syste

进程-IPC 管道 (一)

详见:https://github.com/ZhangzheBJUT/linux/blob/master/IPC(%E4%B8%80).md 一 IPC 概述 进程间通信就是在不同进程之间传播或交换信息,那么不同进程之间存在着什么两方都能够訪问的介质呢?进程的用户空间是互相独立的,一般而言是不能互相訪问的,唯一的例外是共享内存区.系统空间是"公共场所".所以内核显然能够提供这种条件,例如以下图所看到的. 除此以外,那就是两方都能够訪问的外设了.两个进程能够通过磁盘上的普通文件交换信息.

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

进程间通信——Interprocess communication——IPC 每个进程各自有不同的用户地址空间,任何一个进程的全局变量在另一个进程中都看不到,所以进程之间要交换数据必须通过内核,在内核中开辟一块缓冲区,进程A把数据从用户空间拷到内核缓冲区,进程B再从内核缓冲区把数据读走,内核提供的这种机制称为进程间通信. 不同进程间的通信本质:进程之间可看到一份公共资源:而提供这份资源的形式或者提供者不同,造成了通信方式不同. Linux下进程通信方式主要有以下几种: 1.管道---pipe 无

管道通信

管道大致分为两种: 1.匿名管道:这个一般只能用于父进程创建管道传递给子进程,可以父子进程通信 2.有名管道:这种管道存在于文件系统中,所以任意进程都能找到,都可以通过它来通信 API: #include <unistd.h> int pipe(int fds[2]) fds[0] 是读取文件描述符,也就是管道出口 fds[1] 是写文件描述符,也就是管道入口 创建一个匿名管道 成功返回0,失败返回-1 int dup(int oldfd);创建文件描述符的副本 int dup2(int ol

C#命名管道通信

原文:C#命名管道通信 C#命名管道通信 最近项目中要用c#进程间通信,以前常见的方法包括RMI.发消息等.但在Windows下面发消息需要有窗口,我们的程序是一个后台运行程序,发消息不试用.RMI又用的太多了,准备用管道通信来做消息通信. 管道通信以前在大学学过,包括匿名管道和命名管道.匿名管道只能用在父子进程之间:命名管道可以用在两个进程甚至跨服务器通信.这里给出命名管道的示例. 服务器端代码 private static void WaitData() { using (NamedPipe

管道通信之无名管道---pipe()

pipe()函数在子进程产生之前就应该存在. 父子进程之间只进行一次传递 1 /*============================================ 2 > Copyright (C) 2014 All rights reserved. 3 > FileName:onepipe.c 4 > author:donald 5 > details: 6 ==============================================*/ 7 #inclu

PHP多进程编程(2):管道通信

一个进程如果是个人英雄主义,那么多进程就是集体主义.(不严格区分多进程 和 多线程的差别) 你不再是一个独行侠,而是一个指挥家. 独来独往,非常自由自在,但是,很多时候,不如众人拾柴火焰高. 这就是我对多进程的理解.多线程编程的主要问题是:通信 和 同步问题. 更多PHP 多线程编程的背景知识见: PHP多进程编程(一) 在PHP 中,如果光用pcntl ,实现比较简单的通信问题都是很困难的. 下面介绍管道通信: 1. 管道可以认为是一个队列,不同的线程都可以往里面写东西,也都可以从里面读东西.