zoukankan      html  css  js  c++  java
  • 进程间通信--pipe

    管道的两种局限性:

    • 历史上,他们是半双工的(即数据只能够在一个方向上流动). 现在某些系统也提供全双工管道,但是为了最佳的移植性,我们决不应该预先假定系统使用此特性
    • 他们只能够在具有公共祖先的进程间使用. 通常一个管道由一个进程创建, 然后该进程通过调用fork, 此后父,子进程之间就可以使用该管道

    尽管有这两种局限, 但半双工管道仍然是最常用的 IPC 形式.

    管道由调用pipe函数创建:

    #include<unistd.h>

    int pipe(int filedes[2]); 

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

    经由参数filedes返回的两个文件描述符:

    filedes[0]: 读

    filedes[1]: 写

    filedes[1]的输出既是filedes[0]的输入

    由此, 调用fork之后做什么取决于我们想要有的数据流动方向. 对于从父进程到子进程的管道, 父进程关闭管道的读端filedes[0], 子进程则关闭写端filedes[1]. 如代码所示:

    /*******************************************************************************
    * 版权所有:
    * 模 块 名:
    * 文 件 名:pipe.c
    * 实现功能:
    * 作    者:XYZ
    * 版    本:V1.0
    * 日    期:2013.08.19
    * 其他说明:创建一个从父进程到子进程的管道,并且父进程经改管道向子进程传递数据
    ********************************************************************************/
    // pipe.c
    #include<stdio.h>
    #include"apue.h"
    
    int main()
    {
    	int n;
    	int fd[2];
    	pid_t pid;
    	char line[MAXLINE];
    
    	if (pipe(fd) < 0)
    	{
    		perror("pipe error");
    	}
    	if ((pid = fork()) < 0)
    	{
    		perror("fork error");
    	}
    	else if (pid > 0)
    	{
    		// parent
    		close(fd[0]); // close the read pipe
    		write(fd[1], "hello world
    ", 12);
    	}
    	else
    	{
    		// chlid
    		close(fd[1]);  // close the write pipe
    		n = read(fd[0], line, MAXLINE);
    		write(STDOUT_FILENO, line, n);
    	}
    
    	exit(0);
    }
    

     相反, 为了构造从子进程到父进程的管道, 则父进程关闭了写端fd[1], 子进程需关闭读端fd[0].

    当管道的一端被关闭后, 有以下两条规则起作用:

    • 当读一个写端已被关闭的管道时,在所有数据都被读取后,read返回0, 以指示达到了文件的结束处.(从技术方面考虑,管道的写端还有进程时,就不会产生文件的结束.可以复制一个管道的描述符,使得有多个进程对他具有写打开文件描述符. 但是 ,通常一个管道只有一个读进程,一个写进程)
    • 如果写一个读端已被关闭的管道, 则产生信号SIGPIPE.如果忽略该信号或者捉该信号并从其处理程序返回,则write返回-1, error设置为EPIPE.

    在写管道FIFO时,常量PIPE_BUF规定了内核中管道缓冲区的大小.如果对管道调用write,而且要求写的字节数小于等于PIPE_BUF,则此操作不会与其他进程对同一个管道的write操作穿插进行. 但是, 要是有多个进程同时写一个管道,而且有进程要求写的字节数超过PIPE_BUF字节时, 则写操作的数据可能会相互穿插. 用pathconf或者fpathconf函数可以确定PIPE_BUF的值.

     

  • 相关阅读:
    PHP 上传文件限制
    vim设置golang语法高亮 (Centos)
    linux下安装配置go语言环境
    Vim升华之树形目录插件NERDTree安装图解(ubuntu)
    linux下配置Node.js环境
    RabbitMQ的使用(二)- RabbitMQ服务在单机中做集群
    RabbitMQ的使用(一)- RabbitMQ服务安装
    Exceptionless(二)
    Exceptionless
    SQL Server2012如何打开2016的profiler文件
  • 原文地址:https://www.cnblogs.com/xiao13149920yanyan/p/3267497.html
Copyright © 2011-2022 走看看