进程间通信(上)

作者: iamsonormal2333 | 来源:发表于2017-03-02 17:27 被阅读14次

管道

管道分为两种类型:全双工管道与半双工管道。半双工管道即意味着数据只能在一个方向上流动。全双工管道上的数据可以两个方向流动。老旧系统上大多不提供全双工管道,所以为了移植性考虑,应主要使用半双工管道。通常管道只能在具有公共祖先的两个进程间使用。

尽管有局限性,但是半双工管道仍旧是最常用的进程间通信方式。管道通过pipe()函数创建。

      int pipe(int fd[2]);

fd返回两个文件描述符,fd[0]为读而打开,fd[1]为写而打开。我们通过一个例子来说明。

      int fd[2];
      char line[length];
      pipe(fd);
      if(pid = fork()>0) {
          close(fd[0]);
          write(fd[1], "hello world!\n", 12);
      }//parent
      else {
          close(fd[1]);
          n = read(fd[0], line, length);
          printf("%s", line);
      }//child

首先我们创建一个半双工管道,然后通过fork()函数生成子进程。子进程会继承父进程的所有文件描述符,显然fd[0]、fd[1]都继续保存着。然后父进程关闭读通道,子进程关闭写通道,父进程向半双工管道写入一串字符串,然后子进程读入后写入标准输出。

其实实现全双工管道也不是一件复杂的事。我们只需要建立两个半双工管道即可。

      int fd1[2],fd2[2];
      char line1[length],line2[length];
      pipe(fd1);
      pipe(fd2);
      if(pid = fork()>0) {
          close(fd1[0]);
          close(fd2[1]);
          write(fd1[1], "hello world!\n", 12);
          read(fd2[0],line1,length);
          printf("%s", line1);
      }//parent
      else {
          close(fd1[1]);
          close(fd2[0]);
          n = read(fd1[0], line, length);
          write(fd2[1], "hello world!\n", 12);
          printf("%s", line2);
      }//child

FIFO

FIFO有时被称为命名管道。未命名的管道只能在两个有共同祖先的进程之间使用。FIFO是一个半双工管道。

FIFO由mkfifo()函数创建。

      int mkfifo(const char *pathname, mode_t mode);

mode参数指定文件权限位,类似于open函数的第二个参数。而pathname是一个普通的Unix路径名,代表FIFO的位置。

需要注意的是mkfifo()函数只能创建一个新的管道,而打开一个新的管道只能用open()函数。

      #define FIFO1 "tmp/fifo.1"
      #define FIFO2 "tmp/fifo.2"
      char line1[length],line2[length];
      mkfifo(FIFO1, FILE_MODE);
      mkfifo(FIFO2, FILE_MODE);
      if(pid = fork()>0) {
          readfd = open(FIFO1, O_RDONLY, 0);
          writefd = open(FIFO2, O_wDONLY, 0);
          write(writefd, "hello world!\n", 12);
          read(readfd, line1, length);
          printf("%s", line1);
      }//parent
      else {
          readfd = open(FIFO2, O_RDONLY, 0);
          writefd = open(FIFO1, O_wDONLY, 0);
          write(writefd, "hello world!\n", 12);
          read(readfd, line2, length);
          printf("%s", line2);
      }//child

可以看到这和半双工管道很像,可以把理解成存储在Unix系统中的管道。

相关文章

  • 进程间通信(上)

    管道 管道分为两种类型:全双工管道与半双工管道。半双工管道即意味着数据只能在一个方向上流动。全双工管道上的数据可以...

  • linux进程间通信(1)

    一、进程通信概述 1、什么是进程间通信?什么是线程间通信? 进程间通信: 进程间通信就指的是用户空间中进程A与进程...

  • ServiceManager 的启动过程

    ServiceManager 是 Binder 进程间通信的核心组件之一,扮演者 Binder 进程间通信机制的上...

  • 第二十三章 进程间通信介绍(一)

    本章目标: 进程同步与进程互斥 进程间通信目的 进程间通信发展 进程间通信分类 进程间共享信息的三种方式 IPC对...

  • 进程间的通信

    进程间的通信主要分为本机器进程间的通信和不同机器间进程的通信。本文主要描述本机进程间的通信。 一、传统Linux的...

  • 进程间通信

    进程间通信 进程空间相对独立,资源无法相互获取,此时在不同进程间通信需要专门方法 进程间通信就是在不同的进程间进行...

  • 进程间通信,线程间通信

    进程间通信 进程间通信又称IPC(Inter-Process Communication),指多个进程之间相互通信...

  • Android IPC机制

    IPC 即Inter-Process-Communication,含义是进程间通信/跨进程通信。是指多个进程间通信...

  • 进程管理(五)进程间通信、死锁

    (一)进程间通信 除了同步和互斥外,进程间还有其他的通信手段。 进程间的通信 --> IPC (InterProc...

  • Android通过继承Binder类实现多进程通信

    上一篇讲到用AIDL实现进程间通信,地址:Android进程间通信之AIDL AIDL的底层是通过Binder进行...

网友评论

    本文标题:进程间通信(上)

    本文链接:https://www.haomeiwen.com/subject/edocgttx.html