unix 讯息队列实例
unix 消息队列实例
本文来自:http://blog.sina.com.cn/s/blog_413fbf500100vyyj.html
unix系统中进程可以通过消息进行通信,消息是格式化的可变长度的信息单元,包含消息类型、数据长度及数据三部分内容。每个消息都有一个唯一的名称key,同时还有一个唯一的消息队列描述符。
消息队列的使用:
1、建立:
调用: int msgget(int key,int flags);
key为消息队列名称,flags为用户设置标志,一般设置消息队列的访问权限等,权限取值如下:
权限 八进制整数
用户可写 0400
用户可读 0200
同组可写 0040
同组可读 0020
其它可写 0004
用户可读 0002
权限值可加和组合,如 msgget(0x888,0660|IPC_CREAT) 表示创建队列名称为0x888,用户和同组可读写的消息队列,返回队列描述符,如果该消息队列已存在则返回对应的消息队列描述符。
2、发送:
调用: int msgsnd(int msgid,(void*)&mymsg,int msgsz,int msgflg)
msgid为msgget返回的消息队列描述符,mymsg是指向发送消息的结构,结构需要定义,格式如:
struct mymsg{
long mytype; //消息类型
char msgtext[]; //消息内容
}
msgsz是消息内容msgtext的长度,msgflg是消息设置,一般指定无内存存储消息时进程等待还是返回。
函数成功返回0 失败返回 -1
3、接收:
调用 int msgrcv(int msgid,(void*)&mymsg,int msgsz,int msgtyp,int msgflg)
msgid、mymsg、msgsz、msgflg都与msgsnd的一致,msgtyp指定用户读取消息的类型,如:
(1) msgtyp=0,返回Unix消息队列中的第一个消息
(2) msgtyp>0,返回Unix消息队列中类型为msgtyp的第一个消息
(3) msgtyp<0,返回Unix消息队列中小于等于msgtyp绝对值的最低类型的第一个消息
函数成功返回0 失败返回 -1。
4、消息队列的控制:
调用: int msgctl(int msgid,int cmd,(struct msgid_ds *)&buf)
msgid是要操作的队列描述符,cmd是操作类型,如:
IPC_STAT 查看消息队列的状态,结果放入buf指向的结构
IPC_RMID 删除指定的msgid及其相关的队列和结构
IPC_SET 为指定的msgid设置属主标识、同组标识、操作权、最大字节数等
5、自测实例:
//发送方,读取输入,发送到key为0x1234的消息队列中
msgc.c:
#include <sys/msg.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <stdio.h>
#include <sys/errno.h>
struct mymsg
{
long mtype;
char ctx[128];
};
int main(void)
{
struct mymsg mybuf;
int msgid;
int rc = 0;
msgid = msgget(0x1234,0666 | IPC_CREAT);
if(msgid < 0)
{
fprintf(stderr,"open msg %x fail\n",0x1234);
exit(1);
}
memset(&mybuf,0,sizeof(mybuf));
mybuf.mtype = getpid();
printf("Please input your message: \n");
fgets(mybuf.ctx,sizeof(mybuf.ctx),stdin);
rc = msgsnd(msgid,(void*)&mybuf,strlen(mybuf.ctx),IPC_NOWAIT);
if(rc < 0)
{
printf("Send message error,errno: %d\n",errno);
return (rc);
}else
{
printf("Send message success.\n");
}
return 0;
}
//读取方,从0x1234中读取第一条消息并输出
msgs.c:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdio.h>
#include <errno.h>
struct mymsg
{
long mtype;
char ctx[128];
};
int main(void)
{
struct mymsg buf;
int msgid;
int rc = 0;
msgid = msgget(0x1234,0666|IPC_CREAT);
if(msgid <0)
{
fprintf(stderr,"Open msg %x failed.errno: \n",0x1234,errno);
exit(1);
}
memset(&buf,0,sizeof(buf));
rc = msgrcv(msgid,(void*)&buf,sizeof(buf.ctx),0,IPC_NOWAIT);
if(rc < 0)
{
fprintf(stderr,"Receive msg %x failed.errno: \n",0x1234,errno);
exit(1);
}
fprintf(stderr,"Get the message : pid: %d,len:%d,message: %s.\n",buf.mtype,rc,buf.ctx);
return 0;
}
make编译后执行结果:
# ./tmsgc
Please input your message:
hello this is the test message!
Send message success.
# ./tmsgs
Get the message : pid: 925830,len:32,message: hello this is the test message!
.
# ipcs -q //查看ipc
T ID KEY MODE OWNER GROUP
q 186646559 0x00001234 --rw-rw-rw- rk db2grp
本文来自:http://blog.sina.com.cn/s/blog_413fbf500100vyyj.html
unix系统中进程可以通过消息进行通信,消息是格式化的可变长度的信息单元,包含消息类型、数据长度及数据三部分内容。每个消息都有一个唯一的名称key,同时还有一个唯一的消息队列描述符。
消息队列的使用:
1、建立:
调用: int msgget(int key,int flags);
key为消息队列名称,flags为用户设置标志,一般设置消息队列的访问权限等,权限取值如下:
权限 八进制整数
用户可写 0400
用户可读 0200
同组可写 0040
同组可读 0020
其它可写 0004
用户可读 0002
权限值可加和组合,如 msgget(0x888,0660|IPC_CREAT) 表示创建队列名称为0x888,用户和同组可读写的消息队列,返回队列描述符,如果该消息队列已存在则返回对应的消息队列描述符。
2、发送:
调用: int msgsnd(int msgid,(void*)&mymsg,int msgsz,int msgflg)
msgid为msgget返回的消息队列描述符,mymsg是指向发送消息的结构,结构需要定义,格式如:
struct mymsg{
long mytype; //消息类型
char msgtext[]; //消息内容
}
msgsz是消息内容msgtext的长度,msgflg是消息设置,一般指定无内存存储消息时进程等待还是返回。
函数成功返回0 失败返回 -1
3、接收:
调用 int msgrcv(int msgid,(void*)&mymsg,int msgsz,int msgtyp,int msgflg)
msgid、mymsg、msgsz、msgflg都与msgsnd的一致,msgtyp指定用户读取消息的类型,如:
(1) msgtyp=0,返回Unix消息队列中的第一个消息
(2) msgtyp>0,返回Unix消息队列中类型为msgtyp的第一个消息
(3) msgtyp<0,返回Unix消息队列中小于等于msgtyp绝对值的最低类型的第一个消息
函数成功返回0 失败返回 -1。
4、消息队列的控制:
调用: int msgctl(int msgid,int cmd,(struct msgid_ds *)&buf)
msgid是要操作的队列描述符,cmd是操作类型,如:
IPC_STAT 查看消息队列的状态,结果放入buf指向的结构
IPC_RMID 删除指定的msgid及其相关的队列和结构
IPC_SET 为指定的msgid设置属主标识、同组标识、操作权、最大字节数等
5、自测实例:
//发送方,读取输入,发送到key为0x1234的消息队列中
msgc.c:
#include <sys/msg.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <stdio.h>
#include <sys/errno.h>
struct mymsg
{
long mtype;
char ctx[128];
};
int main(void)
{
struct mymsg mybuf;
int msgid;
int rc = 0;
msgid = msgget(0x1234,0666 | IPC_CREAT);
if(msgid < 0)
{
fprintf(stderr,"open msg %x fail\n",0x1234);
exit(1);
}
memset(&mybuf,0,sizeof(mybuf));
mybuf.mtype = getpid();
printf("Please input your message: \n");
fgets(mybuf.ctx,sizeof(mybuf.ctx),stdin);
rc = msgsnd(msgid,(void*)&mybuf,strlen(mybuf.ctx),IPC_NOWAIT);
if(rc < 0)
{
printf("Send message error,errno: %d\n",errno);
return (rc);
}else
{
printf("Send message success.\n");
}
return 0;
}
//读取方,从0x1234中读取第一条消息并输出
msgs.c:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdio.h>
#include <errno.h>
struct mymsg
{
long mtype;
char ctx[128];
};
int main(void)
{
struct mymsg buf;
int msgid;
int rc = 0;
msgid = msgget(0x1234,0666|IPC_CREAT);
if(msgid <0)
{
fprintf(stderr,"Open msg %x failed.errno: \n",0x1234,errno);
exit(1);
}
memset(&buf,0,sizeof(buf));
rc = msgrcv(msgid,(void*)&buf,sizeof(buf.ctx),0,IPC_NOWAIT);
if(rc < 0)
{
fprintf(stderr,"Receive msg %x failed.errno: \n",0x1234,errno);
exit(1);
}
fprintf(stderr,"Get the message : pid: %d,len:%d,message: %s.\n",buf.mtype,rc,buf.ctx);
return 0;
}
make编译后执行结果:
# ./tmsgc
Please input your message:
hello this is the test message!
Send message success.
# ./tmsgs
Get the message : pid: 925830,len:32,message: hello this is the test message!
.
# ipcs -q //查看ipc
T ID KEY MODE OWNER GROUP
q 186646559 0x00001234 --rw-rw-rw- rk db2grp