linux进程间通信消息队列信号量共享内存等.ppt
- 文档编号:1380857
- 上传时间:2022-10-21
- 格式:PPT
- 页数:70
- 大小:664KB
linux进程间通信消息队列信号量共享内存等.ppt
《linux进程间通信消息队列信号量共享内存等.ppt》由会员分享,可在线阅读,更多相关《linux进程间通信消息队列信号量共享内存等.ppt(70页珍藏版)》请在冰豆网上搜索。
桂电嵌入式交流群:
156619189,Linux进程间通信(下),LinuxIPCprogramme,课程目标,SystemVIPC接口简介SystemV消息队列SystemV信号量SystemV共享内存POSIXIPC接口Posix消息队列Posix信号量Posix共享内存,桂电嵌入式交流群:
156619189,SystemVIPC接口,SystemVIPC接口,由于历史原因,linux下的进程通信手段基本上是从Unix平台上的进程通信手段继承而来的.Unix发展做出重大贡献的两大主力AT&T的贝尔实验室及BSD(加州大学伯克利分校的伯克利软件发布中心)在进程间通信方面的侧重点有所不同贝尔实验室对Unix早期的进程间通信手段进行了系统的改进和扩充,形成了“systemVIPC”,通信进程局限在单个计算机内.BSD则形成了基于套接口(socket)的进程间通信机制,可以在跨机器进行通信.由于Unix版本的多样性,电子电气工程协会(IEEE)开发了一个独立的Unix标准,这个新的ANSIUnix标准被称为计算机环境的可移植性操作系统界面(POSIX)。
他也发展出一套新的IPC接口.Linux本身支持POSIX接口.因此也支持POSIX的IPC接口最初UnixIPC包括:
管道、FIFO、信号,SystemVIPC包括:
SystemV消息队列、SystemV信号灯、SystemV共享内存区,PosixIPC包括:
Posix消息队列、Posix信号灯、Posix共享内存区。
SystemVIPC通常在多个操作系统均实现,包括一般的嵌入式Linux系统,因此本课程主要介绍systemVIPC,Linux的IPC,SystemVIPC指以下三种类型的IPC:
SystemV消息队列sys/msg.hSystemV信号灯sys/sem.hSystemV共享内存区sys/shm.h创建或打开函数msgget,semget,shmget控制操作函数msgctl,semctl,shmctl操作函数msgsnd,msgrcv,semop,shmat,shmdt,SystemV关键字,每一个SystemV对象(消息队列,共享内存和信号量)创建时,需要的第一个参数是整数的Key值,头文件把key_t定义为一个整数SystemV创建对象时假设进行IPC通讯双方都取了相同的key值.这样将双方关联起来生成key的方法有三种双方直接设置为一个相同的整数为key值用IPC_PRIVA让系统自动产生一个key值,用ftok函数将一个路径转换为key值,ftok函数,ftok函数把一个已存在的路径名和一个整数标识符转换成一个key_t值,称为IPC键(IPCkey):
#includekey_tftok(constchar*pahtname,intid);如果pathname不存在,或者对调用进程不可访问,ftok返回-1不能保证两个不同的路径名与同一个id值的组合产生不同的键。
用于产生键的pahtname不能是服务器存活期间由它反复创建并删除的文件,否则会导致ftok多次调用返回不同的值,SystemVIPC的类型,报文(Message)队列(消息队列):
消息队列是消息的链接表,包括Posix消息队列systemV消息队列。
有足够权限的进程可以向队列中添加消息,被赋予读权限的进程则可以读走队列中的消息。
消息队列克服了信号承载信息量少,管道只能承载无格式字节流以及缓冲区大小受限等缺点。
共享内存:
使得多个进程可以访问同一块内存空间,是最快的可用IPC形式。
是针对其他通信机制运行效率较低而设计的。
往往与其它通信机制,如信号量结合使用,来达到进程间的同步及互斥。
信号量(semaphore):
主要作为进程间以及同一进程不同线程之间的同步手段。
桂电嵌入式交流群:
156619189,SystemV消息队列,消息队列,消息队列就是一个消息的链表。
可以把消息看作一个记录,具有特定的格式以及特定的优先级。
对消息队列有写权限的进程可以向中按照一定的规则添加新消息;对消息队列有读权限的进程则可以从消息队列中读走消息。
消息队列能够克服早期unix通信机制的一些缺点,如数据量小,没有实时性,消息队列
(2),消息队列消息通常要以一个longmtype放在消息开始,mtype成员代表消息类型,从消息队列中读取消息的一个重要依据就是消息的类型structmsgbuflongmtype;charmtext1;消息队列与管道以及有名管道相比,具有更大的灵活性它提供有格式字节流,有利于减少开发人员的工作量消息具有类型,在实际应用中,可作为优先级使用。
这两点是管道以及有名管道所不能比的消息队列可以在几个进程间复用,而不管这几个进程是否具有亲缘关系,这一点与有名管道很相似;但消息队列是随内核持续的,与有名管道(随进程持续)相比,生命力更强,应用空间更大。
消息队列编程,头文件#include#include#includemsgget打开或创建消息队列intmsgget(key_tkey,intmsgflg);返回线队列IDmsgrcv从队列接收消息intmsgrcv(intmsqid,structmsgbuf*msgp,intmsgsz,longmsgtyp,intmsgflg);msgsnd向队列发送消息intmsgsnd(intmsqid,structmsgbuf*msgp,intmsgsz,intmsgflg);msgctl发送队列控制命令msgctl(intmsqid,intcmd,structmsqid_ds*buf);共有三种cmd操作:
IPC_STAT、IPC_SET、IPC_RMID。
消息队列数据结构,对于系统中的每个SystemV消息队列,内核维护一个如下的结构:
structmsqid_dsstructipc_permmsg_perm;/*operationpermissionstruct*/structmsg*msg_first;/*ptrtofirstmessageonq*/structmsg*msg_last;/*ptrtolastmessageonq*/unsignedshortmsg_cbytes;/*current#bytesonq*/msgqnum_tmsg_qnum;/*#ofmessagesonq*/msglen_tmsg_qbytes;/*max#ofbytesonq*/pid_tmsg_lspid;/*pidoflastmsgsnd*/pid_tmsg_lrpid;/*pidoflastmsgrcv*/time_tmsg_stime;/*lastmsgsndtime*/time_tmsg_rtime;/*lastmsgrcvtime*/time_tmsg_ctime;/*lastchangetime*/;,msgget函数,#includeintmsgget(key_tkey,intoflag);返回:
成功时为非负标识符,出错时为-1用于创建一个新的SystemV消息队列或访问一个已经存在的消息队列。
参数key和oflag的说明见前。
Oflag:
取值,IPC_CREAT创建新对象成功,IPC_EXCL检查新对象返回值是一个整数标识符,其他三个msg函数用它来指代该队列。
当创建一个消息队列时,msqid_ds结构的如下成员被初始化:
msg_perm结构的uid和cuid被设置为当前进程的有效用户ID,gid和cgid被设置为当前用户的有效组ID;oflag中的读写权限位存放在msg_perm.mode中;msg_qnum、msg_lspid、msg_lrpid、msg_stime和msg_rtime被置为0;msg_ctime被设置成当前时间;msg_qbytes被设置为系统限制值。
msgsnd函数,#includeintmsgsnd(intmsgid,constvoid*ptr,size_tlength,intflag);返回:
成功时为0,出错时为-1该函数用于往消息队列上放置一个消息。
msgid是msgget返回的标识符,ptr是一个结构指针,该结构有如下的模板:
structmsgbuflongmtype;/*messagetype,mustbe0*/charmtext1;/*messagedata*/;消息类型mtype必须大于0,因为非正消息类型有特殊的指示作用。
length参数以字节为单位指定待发送消息的长度。
这是位于长整数消息类型之后的用户自定义数据的长度,该长度可以是0。
flag参数可以是0,也可以是IPC_NOWAIT。
IPC_NOWAIT标志使得msgsnd调用非阻塞。
当有如下情形之一时:
在指定的队列中已经有太多的字节(对应msqid_ds结构中的msg_qbytes值);在系统范围存在太多的消息。
若设置了IPC_NOWAIT,则msgsnd立即返回,返回一个EAGAIN错误。
若未指定该标志,则msgsnd阻塞,直到具备存放新消息的空间;有msgid标识的消息队列被删除,此时返回EIDRM错误;被信号中断,此时返回EINTR错误。
msgrcv函数,#includessize_tmsgrcv(intmsqid,void*ptr,size_tlength,longtype,intflag);返回:
成功时为读入缓冲区中数据的字节数,出错时为-1该函数从某个消息队列中读出一个消息。
ptr参数指定所接收消息的存放位置。
跟msgsnd一样,该指针指向紧挨在真正的消息数据之前返回的长整数类型字段。
length指定由ptr指向的缓冲区中数据部分的大小。
这是该函数能返回的最大数据量。
该长度不包含长整数类型字段。
type指定希望从所给定的队列中读出什么样的消息:
type为0,返回队列中第一个消息。
每个消息队列是作为一个FIFO链表维护的,所以返回的是队列中最早的消息。
type大于0,返回其类型值为type的第一个消息。
type小于0,返回其类型值小于或等于type参数的绝对值的消息中类型值最小的第一个消息。
flag参数指定所请求的消息不在队列中时怎么办。
在没有消息时,若设置了IPC_NOWAIT标志,则函数立即返回一个ENOMSG错误;否则,调用者阻塞直到如下某个时间发生:
有一个所请求类型的消息可获取;由msqid标识的消息队列被删除,此时返回个EIDRM错误;被某个捕获的信号中断,此时返回EINTR错误。
msgctl函数,#includeintmsgctl(intmsqid,intcmd,structmsqid_ds*buf);返回:
成功时为0,出错时为-1该函数提供在一个消息队列上的各种控制操作。
msgctl提供三个命令:
IPC_RMID:
从系统中删除由msqid指定的消息队列。
当前在该队列上的任何消息都被丢弃。
此时。
第三个参数忽略不用。
IPC_SET:
给指定的消息队列设置其msqid_ds结构的以下四个成员:
msg_perm.uid、msg_perm.gid、msg_perm.mode和msg_perm.qbytes。
它们的值来自buff指向的结构中的相应成员。
IPC_STAT:
通过buff参数给调用者返回所指定消息队列中的当前msqid_ds结构。
消息队列打开,如果没有调用msgctl(semid,IPC_RMID,0)删除消息队列,则消息队列一直存在内核中,即便是创建进程已经退出也是如此,这个用ipcs可以看到如果对一个已经创建的消息队列的路径再次创建消息队列,通常都会出错.因此可以采用一种保险的写法/*首先查询这个队列是否创建,如创建直接用它*/if(msgid=msgget(key,IPC_EXCL|06
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- linux 进程 通信 消息 队列 信号量 共享 内存