{通信公司管理}linux进程间通信消息队列、信号量、共享内存等)

上传人:卓****库 文档编号:141193422 上传时间:2020-08-05 格式:PPTX 页数:70 大小:620.86KB
返回 下载 相关 举报
{通信公司管理}linux进程间通信消息队列、信号量、共享内存等)_第1页
第1页 / 共70页
{通信公司管理}linux进程间通信消息队列、信号量、共享内存等)_第2页
第2页 / 共70页
{通信公司管理}linux进程间通信消息队列、信号量、共享内存等)_第3页
第3页 / 共70页
{通信公司管理}linux进程间通信消息队列、信号量、共享内存等)_第4页
第4页 / 共70页
{通信公司管理}linux进程间通信消息队列、信号量、共享内存等)_第5页
第5页 / 共70页
点击查看更多>>
资源描述

《{通信公司管理}linux进程间通信消息队列、信号量、共享内存等)》由会员分享,可在线阅读,更多相关《{通信公司管理}linux进程间通信消息队列、信号量、共享内存等)(70页珍藏版)》请在金锄头文库上搜索。

1、Linux进程间通信(下),Linux IPC programme,桂电嵌入式交流群:156619189,课程目标,System V IPC 接口简介 System V 消息队列 System V 信号量 System V 共享内存 POSIX IPC接口 Posix 消息队列 Posix 信号量 Posix 共享内存,System V IPC接口,桂电嵌入式交流群:156619189,System V IPC 接口,由于历史原因, linux下的进程通信手段基本上是从Unix平台上的进程通信手段继承而来的 . Unix发展做出重大贡献的两大主力AT 如果pathname不存在,或者对调用进程

2、不可访问,ftok返回-1 不能保证两个不同的路径名与同一个id值的组合产生不同的键。 用于产生键的pahtname不能是服务器存活期间由它反复创建并删除的文件,否则会导致ftok多次调用返回不同的值,System V IPC的类型,报文(Message)队列(消息队列):消息队列是消息的链接表,包括Posix消息队列system V消息队列。有足够权限的进程可以向队列中添加消息,被赋予读权限的进程则可以读走队列中的消息。消息队列克服了信号承载信息量少,管道只能承载无格式字节流以及缓冲区大小受限等缺点。 共享内存:使得多个进程可以访问同一块内存空间,是最快的可用IPC形式。是针对其他通信机制运

3、行效率较低而设计的。往往与其它通信机制,如信号量结合使用,来达到进程间的同步及互斥。 信号量(semaphore):主要作为进程间以及同一进程不同线程之间的同步手段。,System V 消息队列,桂电嵌入式交流群:156619189,消息队列,消息队列就是一个消息的链表。可以把消息看作一个记录,具有特定的格式以及特定的优先级。对消息队列有写权限的进程可以向中按照一定的规则添加新消息;对消息队列有读权限的进程则可以从消息队列中读走消息。 消息队列能够克服早期unix通信机制的一些缺点 ,如数据量小,没有实时性,消息队列(2),消息队列消息通常要以一个long mtype放在消息开始, mtype

4、成员代表消息类型,从消息队列中读取消息的一个重要依据就是消息的类型 struct msgbuf long mtype; char mtext1; ; 消息队列与管道以及有名管道相比,具有更大的灵活性 它提供有格式字节流,有利于减少开发人员的工作量 消息具有类型,在实际应用中,可作为优先级使用。这两点是管道以及有名管道所不能比的 消息队列可以在几个进程间复用,而不管这几个进程是否具有亲缘关系,这一点与有名管道很相似;但消息队列是随内核持续的,与有名管道(随进程持续)相比,生命力更强,应用空间更大。,消息队列编程,头文件 #include #include #include msgget打开或创建

5、消息队列 int msgget(key_t key, int msgflg) ;返回线队列ID msgrcv从队列接收消息 int msgrcv(int msqid, struct msgbuf *msgp, int msgsz, long msgtyp, int msgflg); msgsnd 向队列发送消息 int msgsnd(int msqid, struct msgbuf *msgp, int msgsz, int msgflg); msgctl 发送队列控制命令 msgctl(int msqid, int cmd, struct msqid_ds *buf); 共有三种cmd操作:

6、IPC_STAT、IPC_SET 、IPC_RMID。,消息队列数据结构,对于系统中的每个System V消息队列,内核维护一个如下的结构: struct msqid_ds struct ipc_perm msg_perm; /* operation permission struct */ struct msg *msg_first; /* ptr to first message on q */ struct msg *msg_last; /* ptr to last message on q */ unsigned short msg_cbytes; /* current # bytes

7、 on q */ msgqnum_t msg_qnum; /* # of messages on q */ msglen_t msg_qbytes; /* max # of bytes on q */ pid_t msg_lspid; /* pid of last msgsnd */ pid_t msg_lrpid; /* pid of last msgrcv */ time_t msg_stime; /* last msgsnd time */ time_t msg_rtime; /* last msgrcv time */ time_t msg_ctime; /* last change

8、time */ ;,msgget函数,#include int msgget(key_t key, int oflag); 返回:成功时为非负标识符,出错时为-1 用于创建一个新的SystemV消息队列或访问一个已经存在的消息队列。 参数key和oflag的说明见前。 Oflag :取值,IPC_CREAT 创建新对象成功,IPC_EXCL检查新对象 返回值是一个整数标识符,其他三个msg函数用它来指代该队列。 当创建一个消息队列时,msqid_ds结构的如下成员被初始化: msg_perm结构的uid和cuid被设置为当前进程的有效用户ID,gid和cgid被设置为当前用户的有效组ID; o

9、flag中的读写权限位存放在msg_perm.mode中; msg_qnum、msg_lspid、msg_lrpid、msg_stime和msg_rtime被置为0; msg_ctime被设置成当前时间; msg_qbytes被设置为系统限制值。,msgsnd函数,#include int msgsnd(int msgid, const void *ptr, size_t length, int flag); 返回:成功时为0,出错时为-1 该函数用于往消息队列上放置一个消息。 msgid是msgget返回的标识符,ptr是一个结构指针,该结构有如下的模板: struct msgbuf lon

10、g mtype; /* message type, must be 0 */ char mtext 1 ; /* message data */ ; 消息类型mtype必须大于0,因为非正消息类型有特殊的指示作用。 length参数以字节为单位指定待发送消息的长度。这是位于长整数消息类型之后的用户自定义数据的长度,该长度可以是0。 flag参数可以是0,也可以是IPC_NOWAIT。IPC_NOWAIT标志使得msgsnd调用非阻塞。当有如下情形之一时: 在指定的队列中已经有太多的字节(对应msqid_ds结构中的msg_qbytes值); 在系统范围存在太多的消息。 若设置了IPC_NOWA

11、IT,则msgsnd立即返回,返回一个EAGAIN错误。若未指定该标志,则msgsnd阻塞,直到具备存放新消息的空间; 有msgid标识的消息队列被删除,此时返回EIDRM错误; 被信号中断,此时返回EINTR错误。,msgrcv函数,#include ssize_t msgrcv(int msqid, void *ptr, size_t length, long type, int flag); 返回:成功时为读入缓冲区中数据的字节数,出错时为-1 该函数从某个消息队列中读出一个消息。 ptr参数指定所接收消息的存放位置。跟msgsnd一样,该指针指向紧挨在真正的消息数据之前返回的长整数类型

12、字段。 length指定由ptr指向的缓冲区中数据部分的大小。这是该函数能返回的最大数据量。该长度不包含长整数类型字段。 type指定希望从所给定的队列中读出什么样的消息: type为0,返回队列中第一个消息。每个消息队列是作为一个FIFO链表维护的,所以返回的是队列中最早的消息。 type大于0,返回其类型值为type的第一个消息。 type小于0,返回其类型值小于或等于type参数的绝对值的消息中类型值最小的第一个消息。 flag参数指定所请求的消息不在队列中时怎么办。在没有消息时,若设置了IPC_NOWAIT标志,则函数立即返回一个ENOMSG错误;否则,调用者阻塞直到如下某个时间发生:

13、 有一个所请求类型的消息可获取; 由msqid标识的消息队列被删除,此时返回个EIDRM错误; 被某个捕获的信号中断,此时返回EINTR错误。,msgctl函数,#include int msgctl(int msqid, int cmd, struct msqid_ds *buf); 返回:成功时为0,出错时为-1 该函数提供在一个消息队列上的各种控制操作。 msgctl提供三个命令: IPC_RMID:从系统中删除由msqid指定的消息队列。当前在该队列上的任何消息都被丢弃。此时。第三个参数忽略不用。 IPC_SET:给指定的消息队列设置其msqid_ds结构的以下四个成员:msg_per

14、m.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,IP

15、C_EXCL|0666) = -1) /*没有创建才去创建这个消息队列*/ msgid=msgget(key,IPC_CREAT|IPC_EXCL|00666); if(msgid=-1) printf(msg create errorn); return; 其它对象也用这样打开方法,System V 信号量,桂电嵌入式交流群:156619189,信号量,信号量与其他进程间通信方式不大相同,它主要提供对进程间共享资源访问控制机制。 信号量相当是一个全局的整数变量,这个变量只能用原子操作来改变值 信号灯与其它进程间通信方式有所不同,它主要用于进程间同步。通常所说的系统V信号灯实际上是一个信号灯的

16、集合,可用于多种共享资源的进程间同步。每个信号灯都有一个值,可以用来表示当前该信号灯代表的共享资源可用(available)数量, 如果一个进程要申请共享资源,那么就从信号灯值中减去要申请的数目,如果当前没有足够的可用资源,进程可以睡眠等待,也可以立即返回。当进程要申请多种共享资源时,linux可以保证操作的原子性,即要么申请到所有的共享资源,要么放弃所有资源,这样能够保证多个进程不会造成互锁。,信号量集的数据结构,SystemV信号灯是信号灯集的概念:一个或多个信号灯构成一个集合。对于系统每个信号灯集,内核维护如下的一个结构: struct semid_ds struct ipc_perm sem_perm; /* operation permission struct */ struct sem *sem_base; /* ptr to first semaphore in set */ unsigned short sem_nsems; /* # of semaphor

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 商业/管理/HR > 企业文档

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号