• 第三季-第13课-无名管道通讯编程


    第13课-无名管道通讯编程

     

    13.1 核心理论

    1. 进程通讯方式

    l  Linux作为一个多进程的操作系统,进程和进程之间是否也需要通讯呢?答案当然是需要的。我们先来看看通讯的目的:

    (1)数据传输

    一个进程需要将数据发送给另一个进程。

    (2)资源共享

    多个进程之间共享同样的资源

    (3)通知事件

    一个进程需要向另一个/组进程发送消息,通知它们发生了某件事。

    (4)进程控制

    有些进程希望完全控制另一个进程的执行(如Debug进程),此时控制进程希望能够拦截另一个进程的所有操作,并能够及时知道它的状态改变。

    l  Linux进程通信(IPC:interprocess communication)由以下几部分发展而来:

    (1)UNIX进程间通信

    (2)基于System V进程间通信

    (3)POSIX进程间通信

    l  POSIX(Portable Operating System Interface)表示可移植操作系统接口。电气和电子工程师协会IEEE最初开发POSIX标准,是为了提高UNIX环境下应用程序的可移植性。然而,POSIX并不局限于UNIX,许多其它的操作系统,例如Microsoft Windows都支持POSIX标准。

    下面介绍7种Linux进程间通讯的主要方式(常作为考试题,得背下来至少5):

    (1)无名管道(pipe):数据传输

    (2)有名管道(FIFO):数据传输

    (3)信号(signal):事件通知

    (4)消息队列

    (5)共享内存:资源共享

    (6)信号量

    (7)套接字(socket)

    2. 管道通讯

    一个进程在管道的尾部写入数据,另一个进程从管道的头部读出数据。管道包括无名管道和有名管道两种,前者只能用于父进程和子进程间的通信,后者可用于运行于同一系统中的任意两个进程间的通信。

    (1)管道通讯是单向的,有固定的读端和写端。

    (2)数据被进程从管道读出后,在管道中该数据就不存在了。

    (3)当进程去读取空管道的时候,进程会阻塞。

    (4)当进程往满管道写入数据时,进程会阻塞。

    (5)管道容量为64KB(#define PIPE_BUFFERS 16 include/linux/pipe_fs_i.h)。

    3. 无名管道

    在Linux系统中,无名管道一旦创建完成后,操作无名管道等同于操作文件。无名管道的读端被视作一个文件;无名管道的写端也被视作一个文件。在我们使用无名管道的时候,我们首先要创建一个无名管道 , 之后的问题就是操作无名管道(读和写),当无名管道的读端和写端一旦被创建就会生成相应的两个文件。我们现在对无名管道的操作具变成了对文件的操作。

    13.1 函数学习---创建无名管道

    (1) 函数名

    pipe

    (2) 函数原形

    int pipe(int pipefd[2]);

    (3) 函数功能

    创建一个无名管道(creats a pipe,a unidirectional单向的 data channel that can be used for interprocess communication)

    (4) 所属头文件

    #include<unistd.h>

    (5) 返回值

    成功:0

    失败:-1

    (6) 参数说明

    pipefd[0]:管道的读端

    pipefd[1]:管道的写端

    l  在linux系统中,无名管道一旦创建完成后,操作无名管道就等同于操作文件。因此使用read,write,close等函数来访问无名管道。

    13.3 范例程序

    创建无名管道,并用于父子进程通讯。创建管道要在fork()之前创建,否则它就只属于父进程。

    #include<unistd.h>

    #include<sys/types.h>

    #include<sys/wait.h>

    #include<stdio.h>

    void main()

    {

             pid_t pid;

             int pipefd[2];

             char c_buf[10];

             /*  1.创建管道  */

             pipe(pipefd);

             /*  2.创建子进程 */

             pid = fork();

             if(pid>0)

             {

                      //父进程写入数据

                      write(pipefd[1],"hello",6);

                      wait(NULL);

                      close(pipefd[1]);

                      exit(0);

             }

             if(pid==0)

             {

                      //子进程读取数据

                      read(pipefd[0],c_buf,6) ;

                      printf("chlid read is %s ",c_buf);

                      close(pipefd[0]);

                      exit(0);

             }

    }

    运行结果:child read is hello

  • 相关阅读:
    linux tar详解
    兼容ie和firefox的日期函数获取两个日期相差的天数
    把Response.Redirect放到TryCatch中出的错误
    如何把string类型转为enum类型

    string.Format的大括号处理
    全国默哀三分钟
    网页快捷键上下翻页(兼容firefox和ie)
    通过免费手机短信来控制电脑“执行者”介绍
    刚刚发现了一个好玩的关于有道的
  • 原文地址:https://www.cnblogs.com/free-1122/p/11346072.html
Copyright © 2020-2023  润新知