




已阅读5页,还剩67页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第5章SystemV进程间通信 1 2 SystemVIPC基础 消息队列 3 信号量通信机制 4 共享内存 为了提供与其他系统的兼容性 Linux也支持三种SystemV的进程间通信机制 消息队列 信号量和共享内存 Linux对这些机制的实施大同小异 我们把信号量 消息队列和共享内存统称SystemVIPC对象 就像每个文件都有一个打开文件号一样 每个对象也都有唯一的识别号 进程可以通过系统调用传递的识别号来存取这些对象 与文件的存取一样 对这些对象的存取也要验证存取权限 SystemVIPC可以通过系统调用对对象的创建者设置这些对象的存取权限 2019 12 21 2 ipcs命令 Ipcs命令用于显示消息队列 共享内存 信号量的信息 q显示消息队列s显示信号量m显示共享内存a详细信息对每一个资源 这个命令会显示 TYPE包括信息队列 q 共享内存 m 或者信号量 s ID资源条目的唯一的表示号KEY应用程序存取资源使用的参数 MODE存取模式和许可权限的标记OWNERandGROUP登录名和用户属主的组号 2019 12 21 3 key值和ID值 Linux系统为每个IPC机制都分配了唯一的ID 所有针对该IPC机制的操作都使用对应的ID 因此 通信的双方都需要通过某个办法来获取ID值 显然 创建者根据创建函数的返回值可获取该值 但另一个进程如何实现呢 由于Linux两个进程不能随意访问对方的空间 一个特殊是 子进程可以继承父亲进程的数据 实现父亲进程向子进程的单向传递 也就不能够直接获取这一ID值 为解决这一问题 IPC在实现时约定使用key值做为参数创建 如果在创建时使用相同的key值将得到同一个IPC对象的ID 即一方创建 另一方获取的是ID 这样就保证了双方可以获取用于传递数据的IPC机制ID值 2019 12 21 4 ftok externkey tftok constchar pathname int proj id 此函数有两个参数 pathname为文件路径名 可以是特殊文件 例如目录文件 也可以是当前目录 而通常也是设置此参数为当前目录 因为当前目录一般都是存在的 且不会被立即删除 第二个参数为一个int型变量 2019 12 21 5 例 ftok的使用 include includemain key tkey key ftok 1 printf thekeyis x n key 2019 12 21 人民邮电出版社出版杨宗德编著 6 ftok ftok函数创建key值过程中使用了该文件属性的st dev和st ino 具体构成如下 key值的第31 24为ftok 第二个参数的低8位 key值的第23 16为该文件的st dev属性的低8位 key值的第15 0为该文件的st ino属性的低16位 因此 如果使用相同的文件路径及整数 得到的key值是唯一的 而唯一的key值创建某类IPC机制时将得到同一个IPC机制 但如果使用相同的key值分别创建一个消息队列和一个信号量 两者没有联系 而文件路径的访问对两个进程来说很容易统一 因此 便捷的实现了两进程通信机制的确定 2019 12 21 7 例 ftok函数和参数的关系 include include include includemain intargc char argv key tkey inti structstatbuf if argc 3 printf errorusage n return1 i atoi argv 2 2019 12 21 8 例 ftok函数和参数的关系 if stat argv 1 2019 12 21 9 第5章SystemV进程间通信 1 2 SystemVIPC基础 消息队列 3 信号量通信机制 4 共享内存 消息队列的基本概念 消息队列就是一个消息的链表 是一系列保存在内核中的消息的列表 用户进程可以向消息队列添加消息 也可以从消息队列读取消息 消息队列与管道通信相比 其优势是对每一个消息指定特定消息类型 接收的时候不需要按队列次序 而是可以根据自定义条件接收特定类型的消息 可以把消息看作一个记录 具有特定的格式以及特定的优先级 对消息队列有写权限的进程可以向消息队列中按照一定的规则添加新消息 对消息队列有读权限的进程则可以从消息队列中读取消息 2019 12 21 11 消息队列属性 2019 12 21 12 消息structmsg结构体 comefrom usr src kernels uname r inlcude linux msg h onemsg msgstructureforeachmessage structmsg msg structlist headm list longm type intm ts messagetestsize structmsg msgseg next void security theactualmessagefollowsimmediately 2019 12 21 13 消息队列 2019 12 21 14 对消息队列的说明 对消息队列的限定 comefrom usr include linux msg h defineMSGMNI16 IPCMNI max ofmsgqueueidentifiers defineMSGMAX8192 INT MAX maxsizeofmessage bytes defineMSGMNB16384 INT MAX defaultmaxsizeofamessagequeue 不同的系统限制值可以通过msgctl函数使用IPC INFO参数获得 2019 12 21 15 消息队列常用的系统调用 2019 12 21 16 创建消息队列 externintmsgget key t key int msgflg 第一个参数key为由ftok创建的key值 第二个参数 msgflg的低位用来确定消息队列的访问权限 如0770 为文件的访问权限类型 此外 还可以附加以下参数值 这些值可以与基本权限以或的方式一起使用 comefrom usr include bit ipc h resourcegetrequestflags defineIPC CREAT00001000 createifkeyisnonexistent defineIPC EXCL00002000 failifkeyexists defineIPC NOWAIT00004000 returnerroronwait 2019 12 21 17 msgget返回说明 成功执行时 返回消息队列标识值 失败返回 1 errno被设为以下的某个值 有时也会返回0 这个时候也是可以正常使用的 EACCES 指定的消息队列已存在 但调用进程没有权限访问它 而且不拥有CAP IPC OWNER权限EEXIST key指定的消息队列已存在 而msgflg中同时指定IPC CREAT和IPC EXCL标志ENOENT key指定的消息队列不存在 同时msgflg中不指定IPC CREAT标志ENOMEM 需要建立消息队列 但内存不足ENOSPC 需要建立消息队列 但已达到系统的最大消息队列容量 2019 12 21 18 例 创建消息队列 include include includeintmain key tkey key ftok 1 printf thekeyis x n key intid id msgget key 1 IPC CREAT 0666 printf id d n id system ipcs 2019 12 21 人民邮电出版社出版杨宗德编著 19 消息队列属性控制 externintmsgctl int msqid int cmd structmsqid ds buf 第一个参数 msqid为消息队列标识符 该值为使用msgget函数创建消息队列的返回值 第二个参数 cmd为执行的控制命令 即要执行的操作 包括以下选项 comefrom usr include linux ipc h Controlcommandsusedwithsemctl msgctlandshmctlseealsospecificcommandsinsem h msg handshm h defineIPC RMID0 removeresource defineIPC SET1 setipc permoptions defineIPC STAT2 getipc permoptions defineIPC INFO3 seeipcs 2019 12 21 20 例 删除消息队列 include include includeintmain key tkey intid key ftok 1 id msgget key 1 IPC CREAT 0666 printf id d n id msgctl id IPC RMID NULL sytem ipcs 2019 12 21 人民邮电出版社出版杨宗德编著 21 发送信息到消息队列 externintmsgsnd int msqid constvoid msgp size t msgsz int msgflg 第一个参数msqid为指定的消息队列标识符 由msgget生成的消息队列标识符 即将消息添加到那个消息队列中 第二个参数msgp为指向的用户定义缓冲区 第三个参数为接收信息的大小 其数据类型为size t 即unsignedint类型 其大小为0到系统对消息队列的限定值 第四个参数用来指定在达到系统为消息队列锁定的界限 如达到字数限制 时应采取的操作 2019 12 21 22 发送信息到消息队列 2 第二个参数其定义如下 comefrom usr include linux msg h messagebufferformsgsndandmsgrevcalls structmsgbuf longmtype typeofmessage charmtext 1 messagetext mtype是一个正整数 由产生消息的进程生成 用于表示消息的类型 因此 接收进程可以用来进行消息选择 消息队列在存储信息时是按发送的先后顺序放置的 mtext是文本内容 即消息内容 此处大小为1 显然不够用 在使用时自己重新定义此结构 2019 12 21 23 发送信息到消息队列 3 第四个参数用来指定在达到系统为消息队列锁定的界限 如达到字数限制 时应采取的操作 如果设置为IPC NOWAIT 如果需要等待 则不发送消息并且调用进程立即返回错误信息EAGAIN 如果设置为0 则忽略标志位 成功调用后 此函数将返回0 否则返回 1 同时将对消息队列msqid数据结构的成员执行下列操作 msg qnum以1为增量递增 msg lspid设置为调用进程的进程ID msg stime设置为当前时间 2019 12 21 24 从消息队列接收信息 externintmsgrev int msqid void msgp size t msgsz longint msgtyp int msgflg 此函数从与msqid指定的消息队列标识符相关联的队列中读取消息 并将其放置到msgp指向的结构中 第一个参数为读的对象 即从哪个消息队列获得消息 第二个参数为一个临时消息数据结构 用来保存读取的信息 其定义与发送信息的第二个参数相同 第三个参数msgsz指定mtext的大小 以字节为单位 如果收到的消息大于msgsz 并且msgflg MSG NOERROR为真 则将该消息截至msgsz字节 消息的截断部分将丢失 并且不向调用进程提供截断的提示 2019 12 21 25 从消息队列接收信息 2 第四个参数msgtyp指定请求的消息类型 msgtyp 0收到队列中的第一条消息 任意类型 msgtyp 0收到第一条msgtyp类型的消息 msgtyp 0收到第一条最低类型 小于或等于msgtyp的绝对值 的消息 第五个参数msgflg指定所需类型消息不在队列上时将要采取的操作 0 表示忽略 IPC NOWAIT 如果消息队列为空 则返回一个ENOMSG 并将控制权交回调用函数的进程 2019 12 21 26 消息队列应用实例 include include include include include include includestructmsgmbuf longmsg type charmsg text 512 2019 12 21 27 消息队列应用实例 intmain intqid key tkey intlen structmsgmbufmsg if key ftok a 1 perror ftok exit EXIT FAILURE if qid msgget key IPC CREAT 0666 1 perror msgget exit EXIT FAILURE 2019 12 21 28 消息队列应用实例 printf IDofthequeueis d n qid puts pleaseinputthemssage if fgets 2019 12 21 29 消息队列应用实例 if msgrcv qid 2019 12 21 30 第5章SystemV进程间通信 1 2 SystemVIPC基础 消息队列 3 信号量通信机制 4 共享内存 信号量基本概念 信号量是操作系统中解决进程或线程同步与互斥的最重要机制之一 Linux内核提供SystemV的信号量机制 用于实现进程之间通信 信号量常用系统调用见下表 2019 12 21 32 信号量集合属性 2019 12 21 33 信号量结构 comefrom usr src kernels uname r include linux sem h Onesemaphorestructureforeachsemaphoreinthesystem structsem intsemval currentvalue intsempid pidoflastoperation 2019 12 21 34 信号量通信机制概念图 2019 12 21 35 创建信号量集合 externintsemget key t key int nsems int semflg 第一个参数为key t类型的key值 一般由ftok函数产生 第二个参数 nsems为创建的信号量个数 各信号量以数组的方式存储 这个数组用于初始化数组对象 第三个参数 semflg用来标识信号量集合的权限 如0770 为文件的访问权限类型 此外 还可以附加以下参数值 这些值可以与基本权限以或的方式一起使用 comefrom usr include bit ipc h resourcegetrequestflags defineIPC CREAT00001000 createifkeyisnonexistent defineIPC EXCL00002000 failifkeyexists defineIPC NOWAIT00004000 returnerroronwait 2019 12 21 36 控制信号量集合 信号量 externintsemctl int semid int semnum int cmd 该函数最多可有四个参数 有可能只有三个参数 第一个参数 semid为要操作的信号量集合标识符 该值一般由semget函数返回 第二个参数为集合中信号量的编号 如果标识某个信号量 此值为该信号量的下标 从0到n 1 如果标识整个信号量集合 则设置为0 第三个参数为要执行的操作 如果是对整个信号量集合 这些操作在 usr include linux ipc h文件中定义 其操作包括IPC RMID IPC SET IPC STAT和IPC INFO 具体含义同msgctl的相关操作 2019 12 21 37 2019 12 21 38 信号量操作 externintsemop int semid structsembuf sops size t nsops 此函数第一个参数为要操作的信号量集合标识符 该值一般由semget函数返回 第二个参数为structsembuf结构的变量 其定义如下 comefrom usr include linux sem h semopsystemcallstakesanarrayofthese structsembuf unsignedshortsem num semaphoreindexinarray shortsem op semaphoreoperation shortsem flg operationflags 2019 12 21 39 信号量操作 2 此结构体有三个成员变量 1 sem num为操作的信号量编号 2 sem op为作用于信号量的操作 该值如果为正整数表示增加信号量的值 如果为负整数表示减小信号量的值 如果为0表示对信号量的当前值进行是否为0的测试 3 sem flg为操作标识 2019 12 21 40 使用信号量实现生产消费问题 生产消费问题是一个经典的数学问题 要求生产者 消费者在固定的仓库空间条件下 生产者每生产一个产品将占用一个仓库空间 生产者生产的产品库存不能越过仓库的存储量 消费者每消费一个产品将增加一个仓库空间 消费者在仓库产品为0时不能再消费 本例中采用信号量来解决这个问题 为了便于理解 本例中使用了两个信号量 一个用来管理消费者 以下为sem produce 一个用来管理生产者 以下为sem custom 即sem produce表示当前仓库可用空间的数量 sem custom用来表示当前仓库中产品的数量 对于生产者来说 其需要申请的资源为仓库中的剩余空间 因此 生产者在生产一个产品前 申请sem produce信号量 当此信号量的值大于0 即有可用空间 将生产产品 并将sem produce的值减去1 因为占用了一个空间 同时 当其生产一个产品后 当前仓库的产品数量增加1 需要将sem custom信号量自动加1 对于消费者来说 其需要申请的资源为仓库中的产品 因此 消费者在消费一个产品前 将申请sem custom信号量 当此信号量的值大于0时 即有可用产品 将消费一个产品 并将sem custom信号量的值减去 因为消费了一个产品 同时 当消费一个产品 当前仓库的剩余空间增加1 需要将sem produce信号量自动加1 2019 12 21 41 第5章SystemV进程间通信 1 2 SystemVIPC基础 消息队列 3 信号量通信机制 4 共享内存 共享内存的基本概念 共享内存允许两个或多个进程共享一个给定的存储区 这一段存储区可以被两个或两个以上的进程映射至自身的地址空间中 数据不需要在进程间复制 所以这是最快的一种IPC 使用共享内存时 多个进程之间对一给定的存储区需进行同步访问 即若一个进程正在将数据放入共享存储区 则在它做完这一操作之前 其他进程不应当去读取这些数据 通常 信号量被用来实现对共享存储的访问 2019 12 21 43 共享内存属性 2019 12 21 44 共享内存IPC原理 2019 12 21 45 共享内存与管道对比 2019 12 21 46 共享内存的常用函数 2019 12 21 47 内存映射 函数mmap将某个文件的指定内容映射到内存空间中 该函数声明如下 includevoid mmap void start size tlength intprot intflags intfd off toffset 此函数将在进程的虚拟地址空间 起始为start 长度为length字节 和与文件描述符fd关联的文件 偏移量为offset 长度为length 之间建立映射 参数start一般情况下设置为NULL 由系统分配 第三个参数prot描述映射的内存权限 该参数是以下选项的组合 PORT READ允许读该内存PORT WRITE允许写该内存PORT EXEC允许执行该内存段PORT NONE该内存段不能被访问 2019 12 21 48 内存映射 参数flags控制程序对该内存段的改变所造成的影响 常用选项如下 MAP PRIVATE 内存段是私有的 对他的修改只在此局部范围内有效 其他进程不可见 MAP SHARED 共享映射 某进程对该段内存空间的更新对其他进程来说是可见的 但该文件的内容并不会立即更新 要更新文件内容 需要调用msync和munmap函数 2019 12 21 49 例 内存映射的使用 include include include include includetypedefstruct charname 4 intage people main intargc char argv pid tresult inti people p map chartemp 2019 12 21 50 例 内存映射的使用 p map people mmap NULL sizeof people 10 PROT READ PROT WRITE MAP SHARED MAP ANONYMOUS 1 0 result fork if result 0 perror fork exit EXIT FAILURE elseif result 0 sleep 2 for i 0 i 5 i printf readbychild No d sageis d n i 1 p map i age 2019 12 21 51 例 内存映射的使用 p map age 110 munmap p map sizeof people 10 exit 0 else temp a for i 0 iname 2019 12 21 52 例 内存映射的使用 sleep 5 printf readbyparent thesumofageis d n p map age printf unmaping n munmap p map sizeof people 10 printf unmapsuccessful n 2019 12 21 53 创建共享内存 externintshmget key t key size t size int shmflg 第一个参数为key t类型的key值 一般由ftok函数产生 第二个参数size为欲创建的共享内存段大小 单位为字节 第三个参数shmflg用来标识共享内存段的创建标识 包括 comefrom usr include linu ipc h defineIPC CREAT01000 Createkeyifkeydoesnotexist defineIPC EXCL020000 Failifkeyexists defineIPC NOWAIT04000 Returnerroronwait 2019 12 21 54 创建共享内存 另外 在 usr include linux shm h文件还定义了另外两个选项 comefrom usr include linux shm h permissionflagforshmget defineSHM R0400 orS IRUGOfrom defineSHM W0200 orS IWUGOfrom 2019 12 21 55 共享内存控制 externintshmctl int shmid int cmd structshmid ds buf 第一个参数为要操作的共享内存标识符 该值一般由shmget函数返回 第二个参数为要执行的操作 这些操作在 usr include linux ipc h文件中定义 其操作包括IPC RMID IPC SET IPC STAT和IPC INFO 具体含义同msgctl的相关操作 如果是超级用户 还可以执行以下两个命令 comefrom usr include sys shm h superusershmctlcommands defineSHM LOCK11 defineSHM UNLOCK12第三个参数为structshmid ds结构的临时共享内存变量信息 此内容根据第二个参数的不一样而改变 2019 12 21 56 映射共享内存对象 进程使用共享内存前 需要将该共享内存与当前进程建立联系 即将该共享内存使用shmat函数映射到当前进程 其函数声明如下 includeexternvoid shmat int shmid constvoid shmaddr int shmflag 如果执行成功 将返回共享内存段首地址 第一个参数 shmid为要操作的共享内存标识符 该值一般由shmget函数返回 第二个参数shmaddr指定共享内存的映射地址 如果该值为非零 则将用此值作为映射共享内存的地址 如果此值为0 则由系统来选择映射的地址 一般都将此值设置为0 2019 12 21 57 映射共享内存对象 includeexternvoid shmat int shmid constvoid shmaddr int shmflag 第三个参数用来指定共享内存短的访问权限和映射条件 comefrom usr include linux shm h modeforattach defineSHM RDNOLY010000 read onlyaccess defineSHM RND020000 roundattachattachaddresstoSHMLBAbounary defineSHM REMAP040000 take overregiononattach defineSHM EXEC0100000 executionaccess 2019 12 21 58 分离共享内存对象 在共享内存使用完毕后 需要使用shmdt函数将其与当前进程分离 其函数声明如下 comefrom usr include sys shm hexternintshmdt constvoid shmaddr 其参数即为与当前进程分离的共享内存标志ID 2019 12 21 59 例一 include include include include include includetypedefstruct charname 4 intage people main intshm id i key tkey people p map char name dev shm myshm2 2019 12 21 60 例一 key ftok name 0 shm id shmget key 4096 IPC CREAT if shm id 1 perror shmget exit EXIT FAILURE p map people shmat shm id NULL 0 for i 0 iname printf age d n p map i age if shmdt p map 1 perror shmdt 2019 12 21 61 例一 include include include include include includetypedefstruct charname 4 intage people main intshm id i key tkey people p map char name dev shm myshm2 2019 12 21 62 例一 key ftok name 0 if key 1 perror ftok exit EXIT FAILURE shm id shmget key 4096 IPC CREAT 0666 if shm id 1 perror shmget exit EXIT FAILURE p map shmat shm id 0 0 people shmat shm id 0 0 temp a for i 0 iname 2019 12
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 离婚书面合同协议书模板:财产分割及子女抚养权处理
- 离婚协议中股权分割与共同债务承担三方协议
- 票据代理与融资租赁合同模板(融资租赁公司)
- 班组操作安全培训内容课件
- 非洲旅游攻略课件
- 2025年泌尿外科学考试模拟试卷答案及解析
- 望洞庭识字课件
- 快递技术员考试题及答案
- 交通银行2025秋招无领导小组面试案例库吉林地区
- 邮储银行2025衡阳市秋招群面模拟题及高分话术
- GB/T 46150.2-2025锅炉和压力容器第2部分:GB/T 46150.1的符合性检查程序要求
- UPS安全培训课件
- 田径大单元教学课件
- 2025年乡镇残联招聘残疾人专职工作者试题集及参考答案解析
- 2025年甘肃省高考历史真题卷含答案解析
- 第13课 美丽中国我的家(教学课件)小学二年级上册 统编版《道德与法治》新教材
- 2025年铜陵枞阳国有资本投资控股集团有限公司公开招聘工作人员8名备考练习试题及答案解析
- 中华优传统文化(慕课版)教案
- 2025年生物结业考试卷及答案
- 塔吊出租安全协议书范本
- 2025四川宜宾五粮液集团旗下环球集团招聘75人笔试参考题库附答案解析
评论
0/150
提交评论