zoukankan      html  css  js  c++  java
  • linux 进程学习笔记-进程pipe管道

    所谓“进程间通信(IPC,inter-process communication)”,按照其目的讲就是让进程之间能够“共享数据”,“传输数据”,“事件通知”等,我所知道的一共有“管道” “信号” “消息队列(报文)” “共享内存” “套接字” 这几种方式。  
    
      
    
      
    
    这里先看看“管道” 
    
    可以将管道想象成生活中的水管,只不过其中流动的是“数据”。一个管道有两个“端”,一个称为“写端”,从这里将数据写入管道,另外一个称为“读端”,用于将数据从管道中读出。 
    
    管道分为非命名管道和命名管道两种,前者一般写成pipe,后者写作named pipe 
    
    <!--[if !supportLists]-->Ÿ <!--[endif]-->pipe 
    
    由于其没有名字(或者说id之类的),所以其无法在两个毫无干系的两个进程间使用。试想一下,进程A创建了一个管道,进程B无法去找到该管道并使用它,因为没有任何可拿去查找的凭据,连名字都没有... 但在一种特殊情况下其是有用的,如下图,假设进程A创建了一个管道: 
    
     
    
    其中的箭头代表数据写入和读出,很明显,进程A可以从管道的写端将数据写入,然后再从读端读出,但这似乎没有什么意义。 
    
    但,如果在管道建立以后,我们将进程A进行一次fork(),有意思的事情发生了, 子进程会复制父进程的大部分信息,这些信息里当然包含了代表了管道读端和写端的两个“描述字”(但管道仍然只有一份,就像被两个进程读写的某个硬盘文件只有一份一样),所以其就演变成下图这个样子: 
    
     
    
    如果此时,我们将上图中左上角以及右下角的两个箭头抛弃掉: 
    
     
    
    这样,A和B之间就建立起了一个通信管道。 
    
      
    
    那么,将上述过程写成代码的形式就很简单了。 
    
    首先是 int pipe(int f[2]),这个函数将创建一个未命名管道,并将管道的读端描述字包含在f[0]中,将写端描述字放在f[1]中,然后你就可以像利用普通文件描述字一样来读写数据了。 
    
    然后是fork函数,再次是int close(int fd) 函数,其用于关闭指定的文件描述字。 
    
    最后是write和read函数,用于读写数据。 
    
    
    #include <stdio.h>
    #include <unistd.h>
    #include <string.h>
    #include <stdlib.h>
     
    #define BUFF_SZ 256
     
    int main()
    {
        printf("app start...
    ");
        
        pid_t          pid;
        int            pipe_fd[2];
        char           buf[BUFF_SZ];
        const char     data[] = "hi, this is the test data";
        int            bytes_read;
        int            bytes_write;
        
        //clear buffer, all bytes as 0
        memset(buf, 0, sizeof(buf));
        
        //creat pipe
        if(pipe(pipe_fd) < 0)
        {
            printf("[ERROR] can not create pipe
    ");
            exit(1);
        }
        
        
        //fork an new process
        if(0 == (pid=fork()))
        {
            //close the write-point of pipe in child process
            close(pipe_fd[1]);
            
            //read bytes from read-point of pipe in child process
            if((bytes_read = read(pipe_fd[0], buf, BUFF_SZ)) > 0)
            {
                printf("%d bytes read from pipe : '%s'
    ", bytes_read, buf);
            }
            
            //close read-point of pipe in child process
            close(pipe_fd[0]);
            exit(0);
        }
        
        
        //close read-point of pipe in parent process
        close(pipe_fd[0]);
        
        //write bytes to write-point of pipe in parent process
        if((bytes_write = write(pipe_fd[1], data, strlen(data))))
        {
            printf("%d bytes wrote to pipe : '%s'
    ", bytes_write, data);
        }
        
        //close write-point of pipe in parent process
        close(pipe_fd[1]);
        
        //wait child process exit
        waitpid(pid, NULL, 0);
        
        printf("app end
    ");
        
        return 0;
    }
     
    输出为:
    app start...
    25 bytes wrote to pipe : 'hi, this is the test data'
    25 bytes read from pipe : 'hi, this is the test data'
    app end
  • 相关阅读:
    PHP mysqli 扩展库(面向对象/数据库操作封装/事务控制/预编译)
    php 下载文件的函数
    PBOC电子钱包与电子现金及QPBOC
    基于PBOC电子钱包的消费过程详解
    PBOC规范下的java卡介绍
    基于PBOC电子钱包的圈存过程详解
    电子钱包和电子现金的区别
    DES,3DES,AES这三种对称密钥的区别与联系
    密钥体系
    关于卡片的主控密钥和应用主控密钥
  • 原文地址:https://www.cnblogs.com/zendu/p/4988377.html
Copyright © 2011-2022 走看看