《106 SYSV进程间通信.ppt》由会员分享,可在线阅读,更多相关《106 SYSV进程间通信.ppt(26页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、10.610.6SYS V SYS V 进程间通信进程间通信内容内容:信号量信号量;消息队列消息队列;共享内存。共享内存。10.6.1 10.6.1 三者三者共有的特性共有的特性IPCIPC资资源源:表表示示单单独独的的消消息息队队列列、共共享享内内存存或是信号量集合。或是信号量集合。三三者者均均有有XXXgetXXXget()及及XXXctlXXXctl()函函数数(XXXXXX代表代表msgmsg,semsem,shmshm三者之一)。三者之一)。1)1)XXXgetXXXget()()函数函数 两个共同参数:两个共同参数:keykey和和oflagoflag。keykey既既可可由由ft
2、okftok()函函数数产产生生,也也可可以以是是IPC_PRIVATEIPC_PRIVATE常常量量,keykey值值是是IPCIPC资资源源的的外外部部表示表示。oflagoflag包括读写权限,还可以包含包括读写权限,还可以包含IPC_IPC_CREATECREATE和和IPC_EXCLIPC_EXCL标标志志位位。它它们们组组合合的的效效果果如下:如下:(1)(1)指指定定keykey为为IPC_PRIVATE,IPC_PRIVATE,保保证证创创建建一一个惟一的个惟一的IPCIPC资源。资源。(2)(2)设设置置oflagoflag参参数数的的IPC_CREATEIPC_CREATE
3、标标志志位位,但但不不设设置置IPC_EXCLIPC_EXCL。如如果果相相应应keykey的的IPCIPC资资源源不不存存在在,则则创创建建一一个个IPCIPC资资源源,否否则则返返回回已已存在的存在的IPCIPC资源。资源。(3)oflag(3)oflag参参数数的的IPC_CREATEIPC_CREATE和和IPC_EXCLIPC_EXCL同同时时设设置置。如如果果相相应应keykey的的IPCIPC资资源源不不存存在在,则则创创建建一一个个IPCIPC资资源源。否否则则返返回回一一个个错错误误信信息。息。2)XXXctl2)XXXctl()()均均提提供供IPC_SETIPC_SET,
4、IPC_STATIPC_STAT和和IPC_RMIDIPC_RMID命命令令。前前两两者者用用来来设设置置或或得得到到IPCIPC资资源源的的状状态态信息,信息,IPC_RMIDIPC_RMID用来释放用来释放IPCIPC资源。资源。共同的操作模式共同的操作模式:都都是是先先通通过过XXXgetXXXget()创创建建一一个个IPCIPC资资源源,返返回回值值是是该该IPCIPC资资源源IDID。在在以以后后的的操操作作中中,均均以以IPCIPC资资源源IDID为为参参数数,以以对对相相应应的的IPCIPC资资源源进行操作。进行操作。别别的的进进程程可可以以通通过过XXXgetXXXget()
5、取取得得已已有有的的IPCIPC资资源源IDID(权权限限允允许许的的话话)并并对对其其操操作作,从而使进程间通信成为可能。从而使进程间通信成为可能。共同的数据结构:每每一一类类IPCIPC资资源源都都有有一一个个ipc_idsipc_ids结结构构的的全全局局变变量量用用来来描描述述同同一一类类资资源源的的公公有有数数据据,三三个个全全局局变变量量分别是分别是semid_dssemid_ds,msgid_dsmsgid_ds和和shmid_dsshmid_ds。structstruct ipc_idsipc_ids intint size;/*entries size;/*entries数组
6、的大小数组的大小*/intint in_use;/*entries in_use;/*entries数组已使用的元素个数数组已使用的元素个数*/intint max_id;max_id;unsigned short unsigned short seqseq;unsigned short unsigned short seq_maxseq_max;tructtruct semaphore semaphore semsem;/*;/*控制对控制对ipc_idsipc_ids结构的访问结构的访问*/spinlock_tspinlock_t aryary;/*;/*自旋锁控制对数组自旋锁控制对数组e
7、ntriesentries的访问的访问*/structstruct ipc_idipc_id*entries;*entries;structstruct ipc_idipc_id structstruct kern_ipc_permkern_ipc_perm*p;*p;数组数组entriesentries的每一项指向一个的每一项指向一个kern_ipc_permkern_ipc_perm结结构构,kern_ipc_permkern_ipc_perm结结构构表表示示每每一一个个IPCIPC资资源源的的属性,用来控制操作权限属性,用来控制操作权限。structstruct kern_ipc_per
8、mkern_ipc_perm key_t key;/*key_t key;/*用户提供的键值用户提供的键值,为为XXXgetXXXget()()所用所用*/uid_tuid_t uiduid;/*;/*创建者用户创建者用户ID*/ID*/gid_tgid_t gidgid;/*;/*创建者组创建者组ID*/ID*/uid_tuid_t cuidcuid;/*;/*所有者用户所有者用户ID*/ID*/gid_tgid_t cgidcgid;/*;/*所有者组所有者组ID*/ID*/mode_t mode;/*mode_t mode;/*操作权限,包括读、写等操作权限,包括读、写等*/unsign
9、ed long unsigned long seqseq;因因为为每每个个IPCIPC资资源源描描述述符符的的第第一一个个成成员员就就是是kern_ipc_permkern_ipc_perm结结构构。因因此此,我我们们可可以以认认为为数数组组entries entries 的每一非空项均指向一个的每一非空项均指向一个IPCIPC资源。资源。IPCIPC资源资源IDID与与entriesentries数组下标的联系:数组下标的联系:1)1)当创建一个当创建一个IPCIPC资源时资源时 2)2)当当知知道道IPCIPC资资源源IDID时时,可可通通过过IPCIPC资资源源ID ID SEQ_MUL
10、TIPLIERSEQ_MULTIPLIER得得到到其其在在entriesentries数数组中的组中的indexindex,从而找到相应的从而找到相应的IPCIPC资源。资源。3)why3)why保保证证在在一一段段时时期期内内IPCIPC资资源源IDID的的惟惟一性。一性。调调用用函函数数ipc_addidipc_addid()从从相相应应ipc_idsipc_ids结结构构的的entriesentries数数组组中中找找出出第第一一个个未未使使用用的的项项,然然后后返返回回其其下标下标indexindex。返回返回IPCIPC资源资源IDIDIPCIPC资源资源ID=ID=SEQ_MULT
11、IPLIERseqSEQ_MULTIPLIERseqindexindexSEQ_ SEQ_ MULTIPLIERMULTIPLIER是是可可用用资资源源的的最最大大数数目目,seqseq是是ipc_idsipc_ids结结构构中中的的seqseq。每每当当分分配配一一个个IPCIPC资资源源时时,ipc_idsipc_ids结构中的结构中的seqseq就增就增1 1。10.6.210.6.2 信号量信号量 信信号号量量是是具具有有整整数数值值的的对对象象,它它支支持持P P,V V原原语语。进进程程可可以以利利用用信信号号量量实实现现同同步步和互斥。和互斥。SYSVSYSV支支持持的的信信号号
12、量量实实质质上上是是一一个个信信号号量量集集合合,由由多多个个单单独独的的信信号号量量组组成成。我我们们称称SYSVSYSV信信号号量量为为信信号号量量集集合合,而而单单个个的的信号量直接称为信号量。信号量直接称为信号量。信号量集合在内核中用结构信号量集合在内核中用结构sem_arraysem_array表示。表示。structstruct sem_arraysem_array structstruct kern_ipc_permkern_ipc_permsem_permsem_perm;time_t time_t sem_otimesem_otime;/*/*最近一次操作时间最近一次操作时间
13、*/time_t time_t sem_ctimesem_ctime;/*/*最近一次的改变时间最近一次的改变时间*/structstruct semsem*sem_basesem_base;/*;/*指向第一个信号量指向第一个信号量*/structstruct sem_queuesem_queue*sem_pendingsem_pending;/*;/*挂起操作队列挂起操作队列*/structstruct sem_queuesem_queue *sem_pending_lastsem_pending_last;structstruct sem_undosem_undo *undo;*undo
14、;unsigned long unsigned long sem_nsemssem_nsems;/*;/*信号量的个数信号量的个数*/;信信号号量量集集合合中中的的每每一一个个信信号号用用结结构构semsem表表示示:structstruct semsem intintsemvalsemval;/*;/*信号量的当前值信号量的当前值*/intintsempidsempid;/*;/*最近对信号量操作进程的最近对信号量操作进程的pidpid*/*/;信信号号量量的的初初始始值值可可以以调调用用函函数数semctlsemctl()进进行行设置。设置。用用户户可可以以调调用用函函数数semopsem
15、op()对对信信号号量量集集合合中中的的一个或多个信号量进行操作。一个或多个信号量进行操作。每一个操作都是每一个操作都是sembufsembuf结构变量:结构变量:structstruct sembufsembuf unsigned short unsigned short sem_numsem_num;/*;/*在在sem_basesem_base 数组中的下标数组中的下标*/short short sem_opsem_op;short short sem_flgsem_flg;intint semop(intsemop(int semidsemid,structstruct sembufs
16、embuf*opsptropsptr,size_t size_t nopsnops););semidsemid:IPC:IPC资源资源IDID opsptropsptr:操作的集合操作的集合 nopsnops:数组数组opsptropsptr的大小的大小 内核必须保证操作数组内核必须保证操作数组opsptropsptr原子的执行原子的执行。sem_numbersem_number指明是对哪一个信号操作。指明是对哪一个信号操作。sem_flagsem_flag指明一些操作标志位,可以有如下值:指明一些操作标志位,可以有如下值:(1)SEM_UNDO(1)SEM_UNDO。当当进进程程结结束束但但
17、还还拥拥有有信信号号量量资资源源时时,应应将将信信号号量量资资源源返返还还给给相相应应的的信信号号量量集集合合。内内核核有有一一个个sem_undosem_undo结结构构用用于于跟跟踪踪这这方方面面的的情情况况,进进程程描描述述符符有有个个semundosemundo成成员员记记录录进进程程这这方方面面的的信息。信息。(2)(2)IPC_NOWAITIPC_NOWAIT。当当操操作作不不能能立立即即完完成成时时,若若IPC_NOWAITIPC_NOWAIT被设置的话,进程立即返回。被设置的话,进程立即返回。否否则则进进程程进进入入睡睡眠眠状状态态,等等待待时时机机成成熟熟时时被被唤醒完成该操
18、作。唤醒完成该操作。sem_opsem_op指指定定具具体体的的操操作作,它它的的值值有有如如下下含义:含义:(1)(1)大大于于0 0,则则将将该该值值加加到到信信号号量量的的当当前前值上。值上。(2)(2)等等于于0 0,那那么么用用户户希希望望信信号号量量的的当当前前值值变变为为0 0。如如果果值值已已经经是是0 0,则则立立即即返返回回。如如果不是果不是0 0,则取决于,则取决于IPC_NOWAITIPC_NOWAIT是否被设置。是否被设置。(3)(3)小小于于0 0,则则要要看看信信号号量量的的当当前前值值是是否否大大于于等等于于sem_opsem_op的的绝绝对对值值。如如果果大大
19、于于等等于于它它的的绝绝对对值值,就就从从信信号号量量的的当当前前值值中中减减去去sem_opsem_op的的绝绝对对值值。如如果果小小于于它它的的绝绝对对值值,则则取决于取决于IPC_NOWAITIPC_NOWAIT是否被设置是否被设置。当当进进程程的的信信号号量量操操作作不不能能完完成成睡睡眠眠时时,需需要要将将一一个个代代表表着着当当前前进进程程的的sem_queuesem_queue结结构构链链入入相相应应的的信信号号 量量 集集 合合 的的 等等 待待 队队 列列,即即 sem_arraysem_array结结 构构 的的sem_pendingsem_pending队列。队列。str
20、uctstruct sem_queuesem_queue structstruct sem_queuesem_queue*next;/*next;/*队列中的下一个元素队列中的下一个元素*/structstruct sem_queuesem_queue*prevprev;/*;/*队列中的前一个元素队列中的前一个元素*/structstruct task_structtask_struct*sleeper;/*sleeper;/*睡眠进程的描述符睡眠进程的描述符*/structstruct sem_undosem_undo*undo;undo;intint pidpid;/*/*睡眠进程的睡眠
21、进程的pidpid*/*/intint status;status;structstruct sem_arraysem_array*smasma;/*;/*所属的信号量集合所属的信号量集合*/structstruct sembufsembuf*sops;/*sops;/*挂起的操作数组挂起的操作数组*/intint nsopsnsops;/*/*挂起的操作个数挂起的操作个数*/.;10.6.310.6.3消息队列消息队列 具具有有权权限限的的进进程程可可以以往往消消息息队队列列中中读读写写消消息息,这就是消息队列支持进程通信的方式这就是消息队列支持进程通信的方式。msgsndmsgsnd()(
22、)函数将消息放入队列中。函数将消息放入队列中。intint msgsnd(intmsgsnd(int msqidmsqid,const const void void*msgpmsgp,size_t size_t msgszmsgsz,intint msgflgmsgflg););msqidmsqid:消息队列的资源消息队列的资源IDID号。号。msgpmsgp:消消息息缓缓冲冲区区的的首首地地址址。消消息息缓缓冲冲区区消消息息的类型及数据两部分组成。的类型及数据两部分组成。msgszmsgsz:消息缓冲区的长度。消息缓冲区的长度。msgflgmsgflg:可以是可以是0 0,也可以是,也可以
23、是IPC_NOWAITIPC_NOWAIT。msgrcvmsgrcv()从从某某个个消消息息队队列列中中读读一一个个消消息息并并将将其其移移出出消息队列。消息队列。intint msgrcv(intmsgrcv(int msqidmsqid,void*,void*msgpmsgp,intint msgszmsgsz,long,long msgtypmsgtyp,intint msgflgmsgflg););msgpmsgp:接收消息的缓冲区首址。接收消息的缓冲区首址。msgszmsgsz:接接收收缓缓冲冲区区的的大大小小,这这是是函函数数能能返返回回的的最最大大数据量。数据量。msgtypms
24、gtyp:指定接收消息的类型。分为三种情况指定接收消息的类型。分为三种情况:值为值为0 0,返回队列中的第一个消息。,返回队列中的第一个消息。值大于值大于0 0,返回类型为,返回类型为msgtypemsgtype的第一个消息。的第一个消息。值小于值小于0 0,则返回类型值小于或等于,则返回类型值小于或等于msgtypemsgtype 的绝对值的消息中类型值最小的第一个消息。的绝对值的消息中类型值最小的第一个消息。msgflgmsgflg:可可 以以 是是 IPC_NOWAITIPC_NOWAIT,还还 可可 指指 定定 为为MSG_NOERRORMSG_NOERROR。MSG_NOERRORM
25、SG_NOERROR允允许许消消息息长长度度大大于于接接收收缓缓冲冲区长度时截短消息返回。区长度时截短消息返回。在内核中消息队列用在内核中消息队列用msg_queuemsg_queue结构表示。结构表示。structstruct msg_queuemsg_queue structstruct kern_ipc_permkern_ipc_perm q_perm;q_perm;time_t time_t q_stimeq_stime;/*/*最近一次最近一次msgsndmsgsnd时间时间*/time_t time_t q_rtimeq_rtime;/*/*最近一次最近一次msgrcvmsgrcv
26、 时间时间*/time_t time_t q_ctimeq_ctime;/*;/*最近的改变时间最近的改变时间*/unsigned long unsigned long q_cbytesq_cbytes;/*;/*队列中的字节数队列中的字节数*/unsigned long unsigned long q_qnumq_qnum;/*/*队列中的消息数目队列中的消息数目*/unsigned long unsigned long q_qbytesq_qbytes;/*;/*队列中允许的最大字节数队列中允许的最大字节数*/pid_tpid_t q_lspidq_lspid;/*;/*最近一次最近一次m
27、sgsndmsgsnd()()发送进程的发送进程的pidpid*/*/pid_tpid_t q_lrpidq_lrpid;/*;/*最近一次最近一次msgrcvmsgrcv()()接收进程的接收进程的pidpid*/*/structstruct list_head q_messages;/*list_head q_messages;/*消息队列消息队列*/structstruct list_head q_receivers;/*list_head q_receivers;/*待接收消息的睡待接收消息的睡 眠进程队列眠进程队列*/structstruct list_head q_senders;
28、/*list_head q_senders;/*待发送消息的睡眠待发送消息的睡眠 进程队列进程队列*/;若若IPC_NOWAITIPC_NOWAIT未未被被设设置置,则则当当消消息息队队列列的的容容量量已已满满时时,发发送送消消息息的的进进程程会会进进入入睡睡眠眠状状态态并并添添加加到到相相应应的的q_sendersq_senders队队列列,而而当当消消息息队队列列中中无无合合适适的的消消息息时时,接接收收进进程程会会进进入入睡睡眠眠状状态态并并添添加加到到相应的相应的q_receiversq_receivers队列。队列。消消息息队队列列中中的的每每个个消消息息都都链链入入q_messag
29、eq_message队队列列中,每个消息用一个中,每个消息用一个msg_msgmsg_msg结构描述。结构描述。structstruct msg_msgmsg_msg structstruct list_head list_head m_list;m_list;/*/*消消息息队队列列链链表表*/long m_type;/*long m_type;/*消息的类型消息的类型*/intint m_tsm_ts;/*;/*消息的长度消息的长度*/structstruct msg_msgsegmsg_msgseg*next;next;/*/*链链接接属属于于这这个个消息的下一个消息片消息的下一个消息片
30、*/;structstruct msg_msgsegmsg_msgseg structstruct msg_msgsegmsg_msgseg*next;*next;msg_msgmsg_msg结结构构只只是是一一个个消消息息头头部部,并并不不包包含含消消息息的的数数据据部部分分。数数据据部部分分的的空空间间紧紧接接msg_msgmsg_msg结结构构分分配配,但但是是当当数数据据部部分分的的空空间间与与msg_msgmsg_msg结结构构所所占占空空间间大大于于一一个个页页面面时时,则则将将其其以以页页面面为为单单位位分分片片。第第一一个个页页面面存存储储msg_msgmsg_msg结结构构与
31、与首首部部分分数数 据据,随随 后后 的的 再再 分分 配配 空空 间间 则则 存存 储储 structstruct msg_msgsegmsg_msgseg结结构构与与剩剩余余的的数数据据,如如果果这这两两者者所所占占空空间间之之和和仍仍大大于于一一个个页页面面,则则继继续续分分配配下下去去。msg_msgsegmsg_msgseg结构用以把消息片链接在一起。结构用以把消息片链接在一起。10.6.4 10.6.4 共享内存共享内存 共共享享内内存存是是多多个个进进程程共共享享的的一一块块内内存存区区域域。不不同同的的进进程程可可把把共共享享内内存存映映射射到到自自己己的的一一块块地地址址空空
32、间间,不不同同的的进进程程进进行行映映射射的的地地址址空空间间不不一一定定相同。相同。共享内存区的进程对该区域的操作是互见的。共享内存区的进程对该区域的操作是互见的。共共享享内内存存没没有有提提供供进进程程同同步步与与互互斥斥的的机机制制,往往需要和信号量配合使用。往往需要和信号量配合使用。相相比比起起其其他他进进程程通通信信方方式式,共共享享内内存存在在进进行行数数据据交交换换方方面面是是效效率率比比较较高高的的。无无需需用用户户态态、核心态切换开销。核心态切换开销。shmgetshmget()函函数数有有一一个个参参数数指指定定共共享享内内存存区区域域的的大大小小,该该函函数数建建立立的的
33、共共享享内内存存区区在在内内核核中中用用shmid_kernelshmid_kernel结构表示。结构表示。structstruct shmid_kernelshmid_kernel structstruct kern_ipc_permkern_ipc_permshm_permshm_perm;structstruct file*file*shm_fileshm_file;intint id;id;unsigned long unsigned long shm_nattchshm_nattch;/*;/*已建立映射的数目已建立映射的数目*/unsigned long unsigned long
34、 shm_segszshm_segsz;/*;/*共享内存区的大小共享内存区的大小*/time_t time_tshm_atimshm_atim;time_t time_tshm_dtimshm_dtim;time_t time_tshm_ctimshm_ctim;pid_tpid_tshm_cpridshm_cprid;pid_tpid_tshm_lpridshm_lprid;shmgetshmget()创创建建的的共共享享内内存存区区域域并并没没有有立立即即分分配配物物理理内内存存,而而是是创创建建一一个个文文件件对对象象shm_fileshm_file来来描描述述该该区区域域,而而该该文
35、文件件属属于于shmshm文文件件系系统统。shmshm文文件件系系统统是是一一个个内内存存文文件件系系统统,它它不不依依赖赖于于磁磁盘盘文文件的内容。件的内容。进进程程调调用用shmatshmat()函函数数建建立立进进程程地地址址空空间间与与共共享享内内存存区区的的映映射射。选选取取进进程程地地址址空空间间的的哪哪一一段段区区间间进进行行映映射射,可可由由用用户户指指定定也也可可委委托托内内核核进进行行选选择择。shmatshmat函函数数找找到到区区间间后后,进进程程分分配配一一个个vm_area_structvm_area_struct结构描述该区间,结构描述该区间,vm_areavm
36、_area_ _structstruct结结构构的的各各项项被被初初始始化化,其其中中filefile成成员员被被初初始始 化化 为为 shm_fileshm_file,而而 vm_opsvm_ops成成 员员 被被 初初 始始 化化 为为shm_vm_opsshm_vm_ops。static static structstruct vm_operations_structvm_operations_struct shm_vm_opsshm_vm_ops=open:open:shm_openshm_open,close:close:shm_closeshm_close,nopage:shmem
37、_nopagenopage:shmem_nopage,;当当进进程程第第一一次次访访问问该该映映射射共共享享内内存存区区的的区区间间地地址址时时,将将触触发发页页面面异异常常,最最终终将将调调用用shmem_nopageshmem_nopage()()函数。该函数处理的大致过程如下:函数。该函数处理的大致过程如下:先先根根据据文文件件和和文文件件位位置置查查找找page page cachecache,因因为为别别的的进进程程可可能能已已经经为为映映射射的的共共享享内内存存区区页页面面申申请请了了一一个个物物理理页页帧帧。如如果果找找到到,修修改改本本进进程程页页表即可。否则继续下一步。表即可
38、。否则继续下一步。检检查查是是否否被被映映射射的的共共享享内内存存区区页页面面已已经经被被访访问问过过,但但换换出出到到交交换换分分区区。如如果果是是,则则调调入入该该页页面,修改进程页表。否则继续下一步。面,修改进程页表。否则继续下一步。被被映映射射的的共共享享内内存存区区页页面面从从未未被被访访问问过过,这这种种情情况况向向内内存存子子系系统统申申请请一一个个物物理理页页帧帧,修修改改进进程页表。程页表。进进程程可可以以调调用用shmdtshmdt()函函数数解解除除地地址址空空间间与与共共享享内内存存区区的的映映射射关关系系,主主要要是是修修改改页页表表及及释释放放vm_area_structvm_area_struct结构。结构。Shm文件对象