struct ipc_perm{ key_t key; //此IPC对象的键值 uid_t uid; //此IPC对象用户ID gid_t gid; //此IPC对象组ID uid_t cuid; //此IPC对象创建进程的有效用户ID gid_t cgid; //此IPC对象创建进程的有效组ID mode_t mode; //此IPC对象的读写权限 ulong_t seq; //IPC对象的序列号 };当使用XXXget函数创建IPC对象的时候,会初始化ipc_perm结构体,将数据成员赋值。其中mode 参数会根据XXXget函数中的flag参数设置模式,若访问一个已存在的IPC对象,则flag设置为0即可。 二。消息队列(include <sys/msg.h>) 消息队列在内核地址空间内被描述为一个链表,每个消息队列都有唯一的一个消息队列标识号。 系统为所有消息队列维护一个msgque链表,链表中的每个节点都有一个指向一个msqid_ds结构的指针, 该结构完整的描述了一个消息队列。 time_t msg_stime; }; 消息队列的相关函数: int msgget(key_t key,int flag); 功能:创建或得到一个消息队列标识符
struct msqid_ds{ struct ipc_perm msg_perm; struct msg* msg_first; struct msg* msg_last; time_t msg_stime; time_t msg_rtime; time_t msg_ctime; ushort msg_cbytes; ushort msg_qnum; ushort msg_qbytes; ushort msg_lspid; ushort msg_lrpid; };key:当被指定为IPC_PRIVATE即0时,会由系统设置key创建新的消息队列 当key大于0时,视参数flag来确定操作 flag:IPC_CREAT:如果这个队列在内核中不存在,则创建它。 IPC_EXCL:当与IPC_CREAT一起使用时,如果这个队列已存在,则创建失败。 返回:成功返回IPC对象标识符,失败返回-1 如果IPC_CREAT单独使用,semget()为一个新创建的消息队列返回标识号,或者返回具有相同 键值的已存在队列的标识号。如果IPC_EXCL与IPC_CREAT一起使用,要么创建一个新的队列, 要么对已存在的队列返回-1。IPC_EXCL单独是没有用的,当与IPC_CREAT结合起来使用时,可 以保证新创建队列的打开和存取。 同时flag为模式标志参数,使用时需要需要与存取权限进行位或(|)运算。 实例代码如下: int id=msgget(IPC_PRIVATE,IPC_CREAT|0600); int msgctl(int msgqid,int cmd,struct msqid_ds* buff) 功能:用于对消息队列对象的控制, msqid:要操作的消息队列标识符 cmd:要执行的操作,可取值包括: IPC_STAT:获得msqid的消息队列头数据到buff中 IPC_SET:设置消息队列的属性,要设置的属性存于buff中,可设置的属性如下: msg_perm.uid,msg_perm.gid,msg_perm.mode以及msg_qbytes 返回:成功返回0,失败返回-1. 实例代码: msqid_id buff; msgctl(id,IPC_STAT,&buff); int msgsnd(int msqid,const void* msgp,size_t msgsz,int msgflg) 功能:将msgp消息写入标识符为msqid的消息队列 msqid:要操作的消息队列标识符 msgp:发送给队列的消息,可以是任何类型的结构,但第一个字段必须为long类型,标明此发 送消息的类型,msgrcv根据此接收消息。msgp的参照格式如下: struct msg{ long type; //大于0,消息类型 <Type> msg_text;//正文 }msgp; <Type>是指这里可以是任意类型的结构数据 msgsz:消息正文的大小,不包含消息类型的4字节,即sizeof(msg)-sizeof(long) msgflg:设定执行的详细操作,可取值如下: IPC_NOWAIT:当消息队列满的时候,函数不等待,直接返回 IPC_NOERROR:发送消息大于size字节,则把消息截断。 返回:成功返回0,失败返回-1. ssize_t msgrcv(int msqid,void* msgp,size_t msgsz,long msgtyp,int msgflg) 功能:从标识符为msqid的消息队列读取消息并存于msgp,读取后的消息将从队列中删除 msqid:要操作的消息队列标识符 msgp: 存放消息的结构体,结构体类型要与msgsnd发送的类型相同 msgsz:要接受消息的大小,不包含消息类型占用的4字节 msgtyp:=0:接收第一个消息 >0:接收类型等于msgtyp的第一个消息 <0:接收类型小于或等于msgtyp绝对值的第一个消息 msgflg:0:阻塞时接收消息,没有符合类型的消息则一直阻塞等待 IPC_NOWAIT:没有可取的消息时,函数返回ENOMSG错误消息 IPC_EXCEPT:与msgtyp配合使用,返回队列中第一个类型部位msgtyp的消息 IPC_NOERROR:消息截断 实例代码如下:
typedef struct msg{ long type; char text[10]; }MSG; int sendmsg(const char* filename,int proj_id) { key_t key=ftok(filename,proj_id); int id=msgget(key,IPC_CREAT|0600); MSG buf; buf.type=1; strcpy(buf.text,"hello"); int sendlength=sizeof(MSG)-sizeof(long); msgsnd(id,&buf,sendlength,0); } int recvmsg(const char* filename,int proj_id) { key_t key=ftok(filename,proj_id); int id=msgget(key,IPC_CREAT|0600); MSG buf; int recvlength=sizeof(MSG)-sizeof(long); msgrcv(id,&buf,recvlength,1,0); printf("%s\n",buf.text); }