首页 > 其他分享 >day06

day06

时间:2023-08-23 20:44:35浏览次数:42  
标签:IPC 间通信 int day06 信号量 进程 共享内存

进程间通信:     一、基本概念:         什么是进程间通信:             指两个或多个进程之间需要协同工作、交互数据的过程,因为进程之间是相互独立工作的,为了协同工作就需要进行通信来交互数据         进程间通信的分类:                                   **(背)**             简单的进程间通信:                 信号(携带附加信息)、文件、环境变量表、命令行参数             传统的进程间通信:                 管道文件(有名管道、匿名管道)             XSI的进程间通信:                 共享内存、消息队列、信号量             网络的进程间通信:                 socket套接字
    二、传统的进程间通信技术——管道         管道是UNIX系统中最古老的进程间通信方式,古老就意味着所有的系统都支持,早期的管道是半双工,现在有些系统的管道是全双工(假定以半双工来编写代码)         管道是一种特殊的文件,它的数据在管道文件中是流动的,读取后就会自动消失,如果文件中没有数据要读取会阻塞等待
        有名管道:             基于有文件名的管道文件的进程间通信,可以是任何进程之间的通信             *编程模型:                     进程A           进程B                    创建管道          ...                    打开管道         打开管道                     写数据          读数据                    关闭管道         关闭管道                    删除管道          ...
                1、创建有名管道文件的方式:                     命令:mkfifo filename                     函数:mkfifo                         int mkfifo(const char *pathname, mode_t mode);                         功能:创建有民法管道文件                         pathname:文件的路径                         mode:文件的权限掩码
        匿名管道:没有名字的管道文件             只适合通过fork创建的有血缘关系的进程间通信(父子进程、兄弟进程之间)             int pipe(int pipefd[2]);             功能:创建并打开一个匿名管道文件                 pipefd:输出型参数  返回该匿名管道文件的读权限fd,和写权限fd两个文件描述符                     pipefd[0]   读                     pipefd[1]   写             *编程模型:                     父进程          子进程                   获取一对fd          ...                   创建子进程       共享父进程fd                    关闭读fd         关闭写fd                   fd[1]写数据      fd[0]读数据                    关闭fd[1]        关闭fd[0]
三、XSI进程间通信     X/open  公司指定的用于进程间通信的系统(S)接口(I)标准     XSI进程间通信标准都需要借助系统内核完成,需要创建内核对象,内核对象以整数形式来返回给用户,相当于文件描述符、文件指针,代表了某个内核对象来完成某次进程间通信任务,也叫做IPC标识符     类似文件的创建需要借助文件名一样,IPC标识符的创建也需要借助IPC键值(整数),也跟文件名一样,要确保IPC键值是独一无二的     一般通过函数生成一个独一无二的IPC键值     key_t ftok(const char *pathname, int proj_id);     功能:生成一个独一无二的IPC键值         pathname:项目路径         proj_id: 项目编号     返回值:根据项目路径+项目编号会自动计算出IPC键值     注意:计算IPC键值的方式不是根据pathname的字符串内容,而是依靠路径的位置,如果提供了假的路径,不管编号都会得到相同的IPC键值,不正确!
    共享内存:         基本特点:             两个或多个进程共享同一块由内核负责维护的物理内存,该物理内存是需要与进程的虚拟内存进行映射后使用         优点:             不需要进行磁盘的读写操作,无需复制操作,是最快的一种IPC机制         缺点:             需要考虑通信的同步问题,一般采用信号来解决                 int shmget(key_t key, size_t size, int shmflg);         功能:创建、获取共享内存             key:IPC键值             size:共享内存的大小,当是获取时,参数无意义,写0即可             shmflg:                 IPC_CREAT   创建、获取共享内存,已存在时会直接获取                 IPC_EXCL    配合IPC_CREAT,如果已存在则返回错误                 0           只获取                 注意:如果是创建IPC_CREAT,需要在后面额外按位或这段共享内存的读写权限         返回值:创建成功返回该共享内存的IPC标识符,失败-1
        void *shmat(int shmid, const void *shmaddr, int shmflg);         功能:虚拟内存与物理内存共享内存映射             shmid:IPC标识符             shmaddr:想要映射的虚拟内存首地址,一般给NULL自动映射             shmflg:                 SHM_RND     只有当shmaddr不是NULL时才有效,当映射的字节数不足一页的整数倍时,会向下取整数倍的页数来映射                 SHM_RDONLY  以只读方式映射内存                 如果不需要以上操作,一般给0即可         返回值:成功返回映射后虚拟内存的首地址,失败返回0xffff ffff || (void*)-1         int shmdt(const void *shmaddr);         功能:取消映射             shmaddr:   映射过的虚拟内存首地址         返回值:成功返回0,失败返回-1         int shmctl(int shmid, int cmd, struct shmid_ds *buf);         功能:删除、控制共享内存             shmid:IPC标识符             cmd:                 IPC_STAT    获取共享内存的属性信息      buf输出型参数                 IPC_SET     设置修改共享内存的属性      buf输入型参数                 IPC_RMID    删除共享内存               buf给NULL即可
        编程模型:               进程A                    进程B            创建共享内存             获取共享内存            映射共享内存             映射共享内存            写数据到内存、并通知     接到通知就读内存            接到通知就读取内存       写数据到内存、并通知             取消映射                  取消映射             删除共享内存                ···     消息队列:         基本特点:是一个由内核维护管理的数据链表,通过消息类型来匹配正确后收发数据         int msgget(key_t key, int msgflg);         功能:创建、获取消息队列             key:IPC键值             msgflg                 IPC_CREAT   创建、获取消息队列,已存在时会直接获取                 IPC_EXCL    配合IPC_CREAT,如果已存在则返回错误                 0           只获取                 注意:如果是创建IPC_CREAT,需要在后面额外按位或这段共享内存的读写权限         返回值:创建成功返回该消息队列的IPC标识符,失败-1         int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);         功能:向消息队列发送消息包             msqid:IPC标识符             msgp:                 struct msgbuf {                    long mtype;       /* 必须是long类型的消息类型 */                    char mtext[1];    /* 根据使用需要来存储数据 */                };               msgsz:只需要数据的字节数,不包括消息类型             msgflg:                 阻塞一般写0                 IPC_NOWAIT  当消息队列满时,不等待立即返回         返回值:成功0,失败-1
        ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,                       int msgflg);         功能:从消息队列中接受读取数据             msqid:PID标识符             msgp:存储数据部分内存首地址             msgsz:数据内存的字节数大小,不包括消息类型,因为不确定对方发送的字节数,建议给大一点             msgtyp:要接收的数据类型                 >0  读取消息类型=msgtyp的消息                 =0  读取消息队列中的第一条消息                 <0  读取消息队列中的消息类型小于等于abs(msgtyp)的消息                     如果同时有多个读取最小的             msgflg:                 IPC_NOWAIT  如果当时消息类型没有匹配,则不阻塞立即返回                 阻塞等待一般给0即可         返回值:成功返回读取到的数据字节数,失败-1
        int msgctl(int msqid, int cmd, struct msqid_ds *buf);         功能:删除、控制消息队列             msqid:IPC标识符             cmd:                 IPC_STAT    获取共享内存的属性信息      buf输出型参数                 IPC_SET     设置修改共享内存的属性      buf输入型参数                 IPC_RMID    删除消息队列               buf给NULL即可
        *编程模型:             进程A                   进程B         创建消息队列             获取消息队列         发送消息msg-a            接收msg-a消息         接收msg-b消息            发送消息msg-b         删除消息队列                ···
信号量:     基本特点:由内核维护的"全局变量",用于记录进程之间共享资源的数量,限制进程对共享资源的访问     信号量更像是一种数据操作锁,本身是不具备数据交换功能,而是通过控制其他的通信资源(共享内存、消息队列、文件···)来实现进程间的通信协调     1、如果信号量的值>0,说明有可以使用的资源,使用时需要将信号量的值-1,然后再使用     2、如果信号量的值=0,说明没有资源可以使用,此时进程会进入休眠,直到信号量的值>0,进程就会被唤醒,执行步骤1     3、当资源使用完毕后,需要先将信号量+1,正在休眠的进程就会被唤醒执行步骤1
    int semget(key_t key, int nsems, int semflg);     功能:创建、获取信号量         key:IPC键值         nsems:信号量的数量         semflg                 IPC_CREAT   创建、获取消息队列,已存在时会直接获取                 IPC_EXCL    配合IPC_CREAT,如果已存在则返回错误                 0           只获取                 注意:如果是创建IPC_CREAT,需要在后面额外按位或这段共享内存的读写权限         返回值:创建成功返回该信号量的IPC标识符,失败-1
        int semop(int semid, struct sembuf *sops, size_t nsops);         功能:对信号量进行加减操作             semid:IPC标识符             sops:                 struct sembuf, containing the following members:                     unsigned short sem_num;  /* 信号量的下标 */                     short          sem_op;   //                         1   信号量+1                         -1  信号量尝试-1,如果为0则休眠阻塞                         0   等待信号量的值为0,否则阻塞休眠                     short          sem_flg;  /* operation flags */                         0           阻塞                         IPC_NOWAIT  不阻塞                         SEM_UNDO    如果进程终止,没有手动还原信号量+1,系统会自动还原+1             nsops:表示sops指针指向多少个连续的结构体,意味着要加减多少个信号量,一般一次只操作一个时写1即可                 int semctl(int semid, int semnum, int cmd, ...);         功能:删除、控制信号量             semid:IPC标识符             semnum:第几个信号量 下标从0开始             cmd:                 IPC_STAT    获取信号量属性                 IPC_SET     设置信号量属性                 IPC_RMID    删除信号量                 GETALL      获取所有的信号量的值                 GETNCNT     获取正在等待减信号量的进程数                 GETVAL      通过返回值获取下标为semnum信号量的值                 GETZCNT     获取正在等待信号量的值为0的进程数                 SETVAL      设置下标为semnum信号量的值                 SETALL      设置所有信号量的值             ···:                 union semun {                     int              val;    /* 用于设置信号量的值 */                     struct semid_ds *buf;    /* 用于获取、设置信号量的属性 */                     unsigned short  *array;  /* 用于批量设置、获取信号量的值 */                 };
        使用流程:             1、创建信号量             2、设置信号量管理的资源数             3、减、加信号量             4、删除信号量

标签:IPC,间通信,int,day06,信号量,进程,共享内存
From: https://www.cnblogs.com/ymy1/p/17652747.html

相关文章

  • day06 - 哈希表part01
    242. 有效的字母异位词讲解classSolution{public:boolisAnagram(strings,stringt){if(s.length()!=t.length())returnfalse;map<char,int>map_s;map<char,int>map_t;for(inti=0;i<s.length()......
  • 20天 hot 100 速通计划-day06
    链表142.环形链表II给定一个链表的头节点head,返回链表开始入环的第一个节点。如果链表无环,则返回null。如果链表中有某个节点,可以通过连续跟踪next指针再次到达,则链表中存在环。为了表示给定链表中的环,评测系统内部使用整数pos来表示链表尾连接到链表中的位置(索引......
  • Java学习Day06
    第四章流程控制语句一、概述1.1、说明在一个程序执行的过程中,各条语句的执行顺序对程序的结果是有直接影响的。也就是说,程序的流程对运行结果有直接的影响。所以,我们必须清楚每条语句的执行流程。而且,很多时候我们要通过控制语句的执行顺序来实现我们要完成的功能。简单来说......
  • Day06-26 内部类
    内部类内部类就是在一个类的内部在定义一个类,比如,A类中定义一个B类,那么B类相对A类来说就称为内部类,而A类相对B类来说就是外部类了。1、成员内部类2、静态内部类3、局部内部类4、匿名内部类importcom.oop.demo10.Outer;​publicclassApplication{  publi......
  • 初学C语言day06--进程影响及类型限定符
    进程映像:程序:存储在磁盘上的可执行文件(二进制文件、脚本文件)进程:正在系统中运行的程序进程映像:进程的内存分布情况:text代码段存储二进制指令、常量,只读的,如果强行修改会产生段错误data数据段初始化过的全局变量、初始化过的静态局部变量bss静态数据段未初......
  • Day06-25 接口
    接口普通类:只有具体实现抽象类:具体实现和规范(抽象方法)都有!接口:只有规范!自己无法写方法~专业的约束!约束和实现分离:面向接口编程~接口就是规范,定义的是一组规则,体现了现实世界中“如果你是...则必须能...”的思想。如果你是天使,则必须能飞;如果你是汽车,则必须能跑;如果......
  • Day06_温故知新
    1.Day5温故知新_1: 2.Day5温故知新_2.format()位置传参和关键字传参: 3.Day5温故知新_3f”“用法表达{}: 4.Day5温故知新_4f'‘新用法: 5.Day5温故知新_5.format新增用法: 6.Day5温故知新_6算数运算符相关: ......
  • 算法学习day06哈希表part01-242、349、202、1
    packageSecondBrush.Hash;/***242.有效字母异位词*现在看到这个题目能想到怎么做,但是具体不知道怎么写*大致思路自己先描述一下:*就是建立一个hash表,然后遍历s,写进表中,遍历t,减去对应的数*hash表就可以理解为数组*/publicclassValidAnagram_242{publi......
  • 八期day06-java基础2
    零python和java字节字符串比较0.1java字节数组和字符串相互转换//1字符串转字节数组v4="彭于晏"byte[]b=v4.getBytes();//默认utf8形式System.out.println(b);//输出对象形式,看不到字节数组System.out.println(Arrays.toString(b));//try{//......
  • day06 6.1 Java基础
    day066.1Java基础【一】Python和Java中的字节与字符串的关系【1】Java中字节数组与字符串之间的转换关系字节数组的创建方式一importjava.lang.reflect.Array;importjava.util.Arrays;publicclassDemo01{publicstaticvoidmain(String[]args){//......