天天看点

进程间通讯--消息队列

         进程间通讯--消息队列

1.  创建消息队列

       #include <sys/types.h>        #include <sys/ipc.h>        #include <sys/msg.h>        int msgget(key_t key, int msgflg);

                   成功返回队列ID,失败返回-1。

参数 说明
key 创建/打开队列key值,由ftok产生,可以直接给常量
msgflg 创建/打开方式IPC_CREAT、IPC_EXCL、IPC_NOWAIT

            通常是msgflg =IPC_CREAT| IPC_EXCL|0666,意思是若不存在key值的队列则创建,否则如果存在则打开队列,0666意思与一般文件权限一样,XXX-本用户,同组用户,其他用户的读写执行的权限。

       # include <sys/types.h>        # include <sys/ipc.h>        key_t ftok(const char *pathname, int proj_id);

//获取pathname相对应的一个键值, pathname必须是存在并且可读取的文件,proj_id表示序号,用来区别同时的存在文件。成功返回key值,失败返回-1。

2.  队列读写

       #include <sys/types.h>        #include <sys/ipc.h>        #include <sys/msg.h>

a)         读取数据――阻塞读取消息队列,直到解除阻塞。

ssize_t msgrcv(int msqid, struct msgbuf *msgp, size_t msgsz, long msgtyp, int msgflg);

参数 说明
msqid 已打开的消息队列id
msgp 接收存放的消息队列缓存结构
msgsz 消息数据长度
msgtyp 消息类型。=0 读取队列中第一个数据。
msgflg

读取标志通常使用IPC_NOWAIT:即没有满足条件的消息,立即返回,此时,错误代码errno=ENOMSG

IPC_EXCEPT:与msgtyp>0配合使用,返回队列中第一个类型不为msgtyp的消息

MSG_NOERROR:截断超长数据

缓冲内容结构如下:

struct msgbuf { long mtype;     char mtext[1];             };

msgrcv()解除阻塞的条件三个条件:

1.  消息队列中有了满足条件的消息(或使用了);

2.  msqid代表的消息队列被删除;

3.  调用msgrcv()的进程被信号中断;

a)         发送数据

int msgsnd(int msqid, struct msgbuf *msgp, size_t msgsz, int msgflg);

参数 说明
msqid 已打开的消息队列id

ght: windowtext 1pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 99pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent;" width="132" valign="top">

msgp

发送存放的消息队列缓存结构
msgsz 消息数据长度
msgflg 消息类型。=0 读取队列中第一个数据。

3.  消息队列控制

       #include <sys/types.h>        #include <sys/ipc.h>        #include <sys/msg.h>            int msgctl(int msqid, int cmd, struct msqid_ds *buf);

          成功返回0,失败返回-1。

参数 说明
msqid 已打开的消息队列id
cmd

控制类型选项

IPC_STAT:取得队列状态

IPC_SET:设置队列属性

IPC_RMID:删除消息队列

buf 存放队列的属性结构

       队列属性如下:

struct msqid_ds {   struct ipc_perm msg_perm;   __time_t msg_stime;   unsigned long int __unused1;   __time_t msg_rtime;   unsigned long int __unused2;       __time_t msg_ctime;   unsigned long int __unused3;   unsigned long int __msg_cbytes;   msgqnum_t msg_qnum;   msglen_t msg_qbytes;   __pid_t msg_lspid;   __pid_t msg_lrpid;   unsigned long int __unused4;   unsigned long int __unused5; };

4.例子:

#include <sys/types.h> #include <sys/msg.h> #include <unistd.h> #define msgkey 0x11000001 struct msg_buf     {         int mtype;         char data[255];     };   int main() {         key_t key;         int msgid;         int ret;         struct msg_buf msgbuf;           key=ftok("/tmp/1",'a');         printf("key =[%x]/n",key);         //msgid=msgget(key,IPC_CREAT|IPC_EXCL|0666);         msgid=msgget(msgkey,IPC_CREAT|IPC_EXCL|0666);         if(msgid==-1)         {                 printf("create error/n");                 return -1;         }           msgbuf.mtype = getpid();         strcpy(msgbuf.data,"test haha");         ret=msgsnd(msgid,&msgbuf,sizeof(msgbuf.data),IPC_NOWAIT);         if(ret==-1)         {                 printf("send message err/n");                 return -1;         }           memset(&msgbuf,0,sizeof(msgbuf));         ret=msgrcv(msgid,&msgbuf,sizeof(msgbuf.data),getpid(),IPC_NOWAIT);         if(ret==-1)         {                 printf("recv message err/n");                 return -1;         }         printf("recv msg =[%s]/n",msgbuf.data);           ret=msgctl(msgid,IPC_RMID,NULL);//删除消息队列         if(ret==-1)         {                 printf("del msg err/n");                 return -1;         }   }

  进程间通讯信息查看:

         ipcs -q  --查看消息队列信息,具体 man ipcs可以看到更多的内容

继续阅读