• Linux进程间通信IPC学习笔记之管道


    基础知识:

    管道是最初的Unix IPC形式,可追溯到1973年的Unix第3版。使用其应注意两点:

    1)没有名字;

    2)用于共同祖先间的进程通信;

    3)读写操作用read和write函数

    #include <unistd.h>
    int pipe(int
    fildes[2]);

    返回:成功返回1,否则返回-1.创建成功的两个文件描述符:f[0]和f[1],前者用来打开读,后者用来打开写。

    #include <unistd.h>
    ssize_t read(int fildes, void *buf, size_t nbyte);
    ssize_t write(int fildes, const void *buf, size_t nbyte);

    测试代码:

    代码1

     1 #include<stdio.h>
     2 #include<unistd.h>
     3 
     4 
     5 int main()
     6 {
     7     int n,fd[2];                // 这里的fd是文件描述符的数组,用于创建管道做准备的
     8     pid_t pid;
     9     char line[100];
    10     if(pipe(fd)<0)                     //   创建管道
    11     printf("pipe create error/n");
    12 
    13     if((pid=fork())<0)              //利用fork()创建新进程
    14     printf("fork error/n");
    15     else if(pid>0)
    16     {   //这里是父进程,先关闭管道的读出端,然后在管道的写端写入“hello world"
    17       close(fd[0]);
    18       write(fd[1],"hello word/n",11);
    19     }
    20     else
    21     {   //这里是子进程,先关闭管道的写入端,然后在管道的读出端读出数据
    22         close(fd[1]); 
    23       n= read(fd[0],line,100);
    24         write(STDOUT_FILENO,line,n);
    25     }
    26     exit(0);
    27 }

    代码2

     1 #include <unistd.h>
     2 #include <stdio.h>
     3 
     4  void client (int, int ) , server (int , int) ;
     5  int main(int argc, char **argv)
     6 {
     7     int pipe1[2] ,pipe2[2];
     8     pid_t childpid;
     9 
    10     pipe(pipe1);/* create two pipes */
    11     pipe(pipe2);
    12 
    13     if ( (childpid = fork () ) == 0) 
    14      {                                      /* child */
    15        close (pipe1[1]) ;
    16        close (pipe2[0]) ;
    17        server (pipe1[0],pipe2[1]) ;
    18        exit (0) ;
    19        }
    20     /* parent */
    21    close (pipe1[0]) ;
    22    close (pipe2[1]) ;
    23    client (pipe2[0], pipe1[1]) ;
    24 
    25    waitpid(childpid, NULL, 0); /* wait for child to terminate */
    26    exit(0) ;
    27 
    28 }
    29 
    30 
    31 void client(int readfd, int writefd)
    32 {
    33     size_t len;
    34     ssize_t n;
    35     char buff[MAXLINEI;
    36  
    37 /* read pathname */
    38     fgets (buff, MAXLINE, stdin) ;
    39     len = strlen(buf f) ;                 /* £gets() guarantees null byte at end */
    40     if (buff [len - 1] == '
    ' )
    41     len--;                                     /* delete newline from £gets() */
    42 
    43  /* write pathname to IPC channel */
    44      write(writefd, buff, len);
    45 
    46  /* read from IPC, write to standard output */
    47      while ( (n = Read(readfd, buff, MAXLINE)) > 0)
    48          write(STD0UT_FILENO, buff, n):
    49 }
    50  void server(int readfd, int writefd)
    51 {
    52      int fd;
    53      ssize_t n;
    54      char buff [MAXLINE + 1];
    55 
    56  /* read pathname from IPC channel */
    57      if ( (n = Read(readfd, buff, MAXLINE) ) == 0)
    58      err-quit("end-of-file while reading pathname"):
    59      buff[n] = '';                      /* null terminate pathname */
    60 
    61      if ( (fd = open(buff, O_RDONLY)) < 0)
    62     {
    63  /* error: must tell client */
    64      snprintf(buff + n, sizeof(buff) - n, ": can't open, %s",strerror(errn0));
    65      n = strlen(buf f) ;
    66      write(writefd, buff, n) ;
    67     }
    68      else 
    69     {
    70  /* open succeeded: copy file to IPC channel */
    71      while ( (n = Read(fd, buff, MAXLINE)) > 0)
    72          write(writefd, buff, n);
    73      close ( fd) ;
    74     }
    75 
    76 }

    参考资料

    win32下的多线程命名管道通信的设计

    linux管道

    pipe fifo简介

    Linux进程线程学习笔记:进程间通信之管道

  • 相关阅读:
    图解iPhone开发新手教程
    究竟什么是关系数据库?
    【设计模式】模板方法模式
    SoftReference
    OpenCV在ARM上的移植
    Luci流程分析(openwrt下)
    delete
    delete
    浅析busybox-1.12.0中ash的脚本命令局限性
    shell总结:读取文件、参数、if、分割字符串、数组长度、空文件、变量赋值、多进程、按行切割文件、查看线程
  • 原文地址:https://www.cnblogs.com/gjianw217/p/3290137.html
Copyright © 2020-2023  润新知