• 进程间通信——管道


    进程间通信——管道
    管道简介
    常说的管道都是匿名半双工管道,匿名半双工管道在系统中是没有实名的,并不可以在文件系统中以任何方式看到该管道。它只是进程的一种资源,会随着进程的结束而被系统清除。管道通信是在UNIX系统中应用比较频繁的一种方式,例如使用grep查找:ls |grep ipc
    顾名思义,匿名半双工管道没有名字,这个特性导致了它在应用方面的局限性:
           1.只能在有具有公共祖先的进程间通信,即或是父子关系进程间、或是在兄弟关系进程间通信。
           2.数据只能在一个方向上移动
    管道创建
    尽管这样,半双工管道还是Linux系统上最常见的通信方式。Linux系统用pipe函数创建一个半双工管道,期函数原型为:
            include<unistd.h>
            int pipe(int fd[2]);
         参数fd是一个长度为2的文件描述符,fd[1]为输入文件描述符,fd[1]为输出文件描述符;函数返回类型为int,0表示成功,-1表示失败。当成功返回时,则自动维护一个从fd[1]到fd[0]的同行管道。
    管道操作
    对管道进行读写,可以通过write和read进行:
                write(fd[1], "create the pipe successfully ! ", 31 ); /*向管道写入端写入数据*/
                         char str[256];
                         read(fd[0], str, sizeof(str) ); /*从管道读出端读出数据*/
           读写时,需要注意的问题:
                         1.当输出端关闭时,对输入端的写操作会产生信号SIGPIPE,说明管道读端已经关闭,并且write操作返回为–1,errno的值为EPIPE,对于SIGPIPE信号可以进行捕捉处理。
                2.read返回0说明管道中没数据,但不能说明输入端是否关闭
    操作流程
        1.创建管道
        2.利用fork创建子进程
        3.控制管道流向
        4.从fd[1]向管道写信息
        5.通过fd[0]从管道渡信息
    创建管道的标准库函数
         #include <stdio.h>
             FILE *popen( const char * command, const char *mode ); 
             int pclose ( FILE *stream );  
    示例
    引用《Linux C程序设计大全》 中的例子

    1. #include <unistd.h>
    2. #include <stdio.h>
    3. #include <fcntl.h>
    4. #include <sys/types.h>
    5. #define BUFES PIPE_BUF /* PIPE_BUF管道默认一次性读写的数据长度*/
    6. int main ( void ) {
    7.          int fd[2];
    8.          char buf[BUFSZ];
    9.          pid_t pid;
    10.          int len;
    11.          if ( (pipe(fd)) < 0 ){ /*创建管道*/
    12.                   perror ( "failed to pipe" );
    13.                   exit( 1 );
    14.          }
    15.          if ( (pid = fork()) < 0 ){ /* 创建一个子进程 */
    16.                   perror ( "failed to fork " );
    17.                   exit( 1 );
    18.          }
    19.          else if ( pid > 0 ){
    20.                 close ( fd[0] ); /*父进程中关闭管道的读出端*/
    21.                  write (fd[1], "hello my son! ", 14 ); /*父进程向管道写入数据*/
    22.                  exit ( 0);
    23.          }
    24.          else {
    25.                  close ( fd[1] ); /*子进程关闭管道的写入端*/
    26.                 len = read (fd[0], buf, BUFS ); /*子进程从管道中读出数据*/
    27.         if ( len < 0 ){
    28.                  perror ( "process failed when read a pipe " );
    29.                  exit( 1 );
    30.         }
    31.          else
    32.                  write(STDOUT_FILENO, buf, len); /*输出到标准输出*/
    33.                  exit(0);
    34.          }
    35. }
    阅读(375) | 评论(0) | 转发(2) |
    给主人留下些什么吧!~~
    评论热议
  • 相关阅读:
    nodejs gulp如何获取参数
    nodejs 获取当前路径的方法
    gulp 如何排除文件和文件夹
    小技巧css解决移动端ios不兼容position:fixed属性,无需插件
    代码协议相关
    zen-coding
    directive 实例讲解
    angular api 地址
    一步一步搭建hibernate4+ spring+ struts2
    华为荣耀6 H60-L02/L12(联通版)救砖包【适用于无限重启】
  • 原文地址:https://www.cnblogs.com/black/p/5171656.html
Copyright © 2020-2023  润新知