zoukankan      html  css  js  c++  java
  • 6.进程间通信

    一.基本概念
     进程间通信:进程之间交换数据的过程叫进程间通信。
     进程间通信的方式:、
     
      简单的进程间通信:
       
       命令行:父进程通过exec函数创建子进程时可以附加一些数据
       环境变量表:父进程通过exec函数创建子进程顺便传递一张环境变量表
       信号:父子进程之间可以根据进程号相互发送信号,进程简单通信
       文件:一个进程向文件中写入数据,另一个进程从文件中读取出来。
      命令行,环境变量只能单向传递,信号太过于简单,文件通信不能实时。
      XSI通信方式:X/open 计算机制造商组织。
       共享内存,消息队列,信号量,
      网络进程间通信方式:
       网络通信就是不同机器的进程间通信方式
    传统的进程间通信方式:管道
    二.管道
      1.管道是一种古老的通信方式(基本上不再使用)
      2.早期的管道是一种半双工,现在大多数是全双工的
      3.有名管道(管道是以文件的方式存在的)
       创建管道文件:
        命令mkfifo
        函数mkfifo
        #include <sys/types.h>
              #include <sys/stat.h>
              int mkfifo(const char *pathname, mode_t mode);
            管道通信的编程模式:
             进程A 进程B
             创建管道mkfifo
             打开管道文件open 打开管道
             写/读数据write/read 读/写数据
             关闭管道close 关闭管道
            4.无名管道:由内核帮助创建,只返回管道的文件描述符,看不到管道文件,这种管道只能用于fork创建的父子进程之间
              int pipe(int pipefd[2]);
              pipefd[0]用来读数据
              pipefd[1]用来写数据
              练习:使用无名管道让父子进程通信
    三.XSI IPC进程间通信
     1.XSI通信是依靠内核的IPC对象进程通信
     
     2.每一个IPC对象都有一个IPC标识(类似文件描述符),IPC标识符是一个非负整数。
     3.IPC对象必须要先创建,创建后才能进程获取,设置,操作,删除。
     4.创建IPC对象必须要提供一个键值(key_t),键值是创建获取IPC对象的依据
     5.产生键值的方法:
      固定的字面值:1980014
     
      使用函数计算:ftok(项目路径,项目id)
      使用宏让操作系统随机分配:IPC_PRIVTE
       必须把获取到的IPC对象标识符记录下来,告诉其他进程
     6.XSI可以创建的IPC对象有:
      共享内存,消息队列,信号量
    四.共享内存
     1.由内核维护一块共享的内存区域,其他进程把自己的虚拟地址映射到这块内存,然后多个进程之间共享这块内存了。
     2.这种进程间通信的好处是不需要信息复制,它是进程间通信最快的一种方式
     3.这种方式会面临同步的问题,需要与其他的通信方式配合,最合适的方式就是信号。
     共享内存的编程模式:
      1.进程之间要约定一个键值
      进程A 进程B
      创建共享内存
      加载共享内存 加载共享内存
      卸载共享内存 卸载共享内存
      销毁共享内存
         int shmget(key_t key, size_t size, int shmflg);
         功能:创建共享内存
         size:大小
         模式:
         返回值:IPC对象标识符(类似于文件描述符)
         void *shmat(int shmid, const void *shmaddr, int shmflg);
         功能:加载共享内存()
         
         shmid:shmget的返回值
         
         shmaddr:进程提供的虚拟地址,也可以为NULL,如果为空,操作系统会自动选择一块地址映射
         
         shmflg:
          SHM_RDONLY:映射内存的权限为只读
          SHM_REMAP:映射已经存在的内存共享
          SHM_RND:当shmaddr为空时自动分配
          mode_flag:权限
     int shmdt(const void *shmaddr);
     功能:这个地址对应的共享内存取消映射关系
     #include <sys/ipc.h>
        #include <sys/shm.h>
        int shmctl(int shmid, int cmd, struct shmid_ds *buf);
        功能:控制/销毁共享内存
        cmd:
         IPC_STAT:获取共享内存的属性
         IPC_SET:设置共享内存的属性
         IPC_RMID:删除共享内存
        buf:
         记录共享内存属性的对象
    五.消息队列
     1.消息队列是一个由系统内核负责存储和管理,并通过IPC对象标识符获取的数据链表
        #include <sys/types.h>
           #include <sys/ipc.h>
           #include <sys/msg.h>
           int msgget(key_t key, int msgflg);
           msgflg:
            创建IPC_CREAT | IPC_EXCL
            获取:0
        int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
            功能:向消息队列发送消息
           
            msqid:msgget的返回值
            msgp:消息(消息类型+消息内容)的首地址
            msgsz:消息内容的长度(不包含消息类型)
            msgflg:
             
        ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,
                          int msgflg);
           功能:从消息队列接收消息
           
           msgp:存储消息的缓冲区
           
           msgsz:要接收的消息长度
           
           msgtyp:要接收消息的类型,(包含在消息的前四个字节)
           
           msgflg:
           
            MSG_NOERROR:当消息的实际长度大于msgsz,则按照msgsz长度截取再发送,否则产生错a
            MSG_NOWAIT:如果想要接收的消息不存在,则直接返回。
             否则阻塞等待。
            MSG_EXCEPT:从消息队列中接收第一个不是msgtype类型的第一个消息
        int msgctl(int msqid, int cmd, struct msqid_ds *buf);
        功能:控制/销毁消息队列
        cmd:
         IPC_STAT:获取消息队列的属性
         IPC_SET:设置消息队列的属性
         IPC_RMID:删除消息队列
    六.IPC相关命令:
     ipcs -m 查看共享内存
     ipcrm -m id 删除共享内存
     ipcs -q 查看消息队列
     ipcrm -q id 删除消息队列
    七.信号量
     信号量(信号灯),可以当作进程与进程之间共享的全局变量,一般用来为共享的资源计数
     信号量的使用方法:
      1.进程A,创建信号量,并设置信号量的初始值(设置资源数)
      2.进程B,获取信号量,查看信号量(查询剩余资源的数量),减少信号量(使用资源),增加信号量(资源使用完毕归还)
      3.当一个进程减少信号量时,如果不能减(资源使用完毕),则进程可以进入等待状态,当信号量能够被减的时候(其他进程把资源还回来了),进程会被唤醒
        #include <sys/types.h>
           #include <sys/ipc.h>
           #include <sys/sem.h>
           int semget(key_t key, int nsems, int semflg);
           功能:创建获取获取信号量
           nsems:信号量的数量
           semflg:
             IPC_CREAT
             IPC_EXCL
             0644之类的权限码
           int semop(int semid, struct sembuf *sops, unsigned nsops);
           功能:对信号量增加或减少
           struct sembuf {
              unsigned short sem_num;
              short sem_op;
              short sem_flg; // IPC_NOWAIT标识不阻塞
           }
           int semctl(int semid, int semnum, int cmd, ...);
           功能:对信号量的控制或释放
           semnum:信号量的编号
           cmd:
             IPC_SET 设置信号量的属性
             IPC_STAT 设置信号量的属性
             IPC_RMID 删除信号量
             IPC_INFO 获取信号量的信息

  • 相关阅读:
    使用Xshell和Xftp部署简单的项目
    1-27 sed基本编程和cut基本应用
    1-26-1-expect无交互式-正则表达式
    1-24-case流程控制和while循环语句的使用
    1-23-shell脚本之-if流程控制语句和for循环语句的使用
    1-22-shell脚本基本应用-实验手册
    1-22-shell脚本的基础
    1-21 网络管理相关的命令
    总结 1-1 ~ 1-6
    windows系统下Eclipse启动界面更改
  • 原文地址:https://www.cnblogs.com/LyndonMario/p/9391319.html
Copyright © 2011-2022 走看看