POSIX 和 System V 消息队列!涉及到的函数总结!

消息队列(也叫做报文队列)能够克服早期unix通信机制的一些缺点。信号这种通信方式更像"即时"的通信方式,它要求接受信号的进程在某个时间范围内对信号做出反应,因此该信号最多在接受信号进程的生命周期内才有意义,信号所传递的信息是接近于随进程持续的概念(process-persistent);管道及有名管道则是典型的随进程持续IPC,并且,只能传送无格式的字节流无疑会给应用程序开发带来不便,另外,它的缓冲区大小也受到限制  消息队列就是一个消息的链表。可以把消息看作一个记录,具有特定的格式以及特定的优先级。对消息队列有写权限的进程可以向中按照一定的规则添加新消息;对消息队列有读权限的进程则可以从消息队列中读走消息。消息队列是随内核持续的。

     POSIX 消息队列的函数
      1. mq_open 创建一个新的消息队列或者打开一个已经从存在的消息队列!
       #include<mqueue.h>
          mqd_t mq_open(const char *name,int oflag,)
这个函数成则返回消息队列的描述符,出错则返回-1;在创建一个新的消息队列时后面的2个参数是需要的,其中第4个参数 attr 用来给新队列指定某写属性!若为NULL 则采用默认属性!第3个参数 mode 用来设置 主 组 和其他成员 的读写权限!
          mq_close:关闭已经打开的消息队列!int mq_close(mqd_t mqdes);该函数只是释放掉来文件描述符!要从内存中删除消息队列要用mq_unlink()函数!int mq_unlink(const char *name)!
2. mq_getattr 和 mq_setattr 函数:
每个消息队列有四个属性,mq_getattr 用来返回这些属性! mq_setattr 用来设置其中的某个属性!
#inlcude <mqueue.h>
int mq_getattr(mqd_t mqdes ,struct mq_attr *attr)
int mq_setattr(mqd_t mqdes,const struct mq_attr *attr,struct mq_attr *oattr)
成功返回0,失败返回-1;
struct mq_attr
{
       long mq_flags;
       long  mq_maxmsg;
       long  mq_msgsize;
       long  mq_curmsgs;
}
3.mq_send 和 mq_receive 函数
往队列中放一个消息 和从 消息队列中去走一个消息!
#include <mqueue.h>
int mq_send (mqd_t mqdes, const char *ptr , size_t len, unsigned int prio);
int mq_receive (mqd_t mqdes, const char *ptr , size_t len, unsigned int *prio)

System V 消息队列:
使用消息队列描述符标示:有足够特权的任何进程可以读 或 写一个消息队列!
对于系统的每个消息队列,内核维护一个定义在<sys/msg.h> 的结构:
struct msqid_ds{
        .
        .
        .
}
其中包括了一个结构体:struct ipc_perm {
                                                            ....
                                                         }
这个结构体保存消息队列的重要属性,比如消息队列的键值,消息队列的用户组ID ,组ID 定义在头 linux/ipc.h 中;这些东西就是msgget 中 oflag 的读写权限位存放在 msg_perm.mode 中!


 
1.msgget 函数
#include <sys/msg.h>
int msgget (key_t key,int oflag)
其中 key 可以通过 ftok 和 IPC_PRIVATE 设定!

ftok函数       (IPC_PRIVATE自动产生一个键值)系统建立IPC通讯(如消息队列、共享内存时)必须指定一个ID值。通常情况下,该id值通过ftok函数得到。
ftok原型如下:
key_t ftok( char * fname, int id )
fname就时你指定的文件名,id是子序号。

在一般的UNIX实现中,是将文件的索引节点号取出,前面加上子序号得到key_t的返回值。

如指定文件的索引节点号为65538,换算成16进制为0x010002,而你指定的ID值为38,换算成16进制为0x26,则最后的key_t返回值为0x26010002。
查询文件索引节点号的方法是: ls -i
测试小程序
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>

#define IPCKEY 0x11
int main( void )
{
    int i=0;
    for ( i = 1; i < 256; ++ i )
        printf( "key = %x\n", ftok( "/tmp", i ) );

    return 0;
}
当删除重建文件后,索引节点号由操作系统根据当时文件系统的使用情况分配,因此与原来不同,所以得到的索引节点号也不同。


2.msgsnd  和 msgrcv 函数:
#include <sys/msg.h>
int msgsnd (int msqid, const void *ptr , size_t length , int flag);
成功返回0  失败返回-1;
ssize_t msgrcv (int msqid,void *ptr,size_t length, long type,int flag);
成功返回 读入缓存区的数据字节,出错返回 -1;
其中 ptr 是结构题指针;
struct msgbuf
{
   long mtype;
   char mtext[1];
}

3. msgctl 函数:
#include <sys/msg.h>
int msgctl (int msgid,int cmd, struct msqid_ds *buff);
在消息队列上的操作!

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/23333.html