您的位置:首页 > 其它

消息队列

2013-11-04 10:59 148 查看
消息队列是消息的链接表,存放在内核中并由消息队列标识符标识,消息队列提供了一种由一个进程向另一个进程发送块数据的方法

#include<sys/msg.h>

int msgctl(int msgqid, int cmd, struct msqid_ds *buf);

第一个参数,msqid,是由msgget函数所返回的标识符

第二个参数,cmd,是要执行的动作

IPC——STAT ,取此队列的msqid_ds结构,并将它存放在buf指向的结构中

IPC——SET,按由buf指向结构中的值,设置与此队列相关结构中的下列四个字段:msg_perm.uid,msg_perm.gid,msg_perm.mode和msg_qbytes

IPC——RMID,删除消息队列

int msgget(key_t key, int msgflg);

第一个参数,与其他IPC工具类似,程序必须提供一个指定一个特定消息队列的key值特殊值IPC_PRIVATE创建一个私有队列,这在理论上只可以为当前进程所访问

第二个参数,msgflg,由9个权限标记组成,要创建一个新的消息队列,由IPC_CREAT特殊位必须与其他的权限位进行或操作

int msgsnd(int msqid, const void *msg_ptr, size_t msg_sz, int msgflg);

第二个参数,msg_ptr,是一个指向要发送消息的指针,这个消息必须以long int 类型开始

第三个参数,msg_sz,是由msg_ptr所指向的消息的尺寸,这个尺寸必须不包含long int 消息类型

第四个参数,msgflag,控制如果当前消息队列已满或是达到了队列消息的系统限制时如何处理,如果msgflag标记设置了IPC_NOWAIT,函数就会立即返回而不发送消息,并且返回值为-1,如果msgflg标记清除了IPC_NOWAIT标记,发送进程就会被挂起,等待队列中有可用的空间

int msgrcv(int msqid, void *msg_ptr, size_t msg_sz, long int msgtype, int msgflag);

第二个参数,msg_ptr,是一个指向要发送消息的指针,这个消息必须以long int 类型开始

第三个参数,msg_sz,是由msg_ptr所指向的消息的尺寸,这个尺寸必须不包含long int 消息类型

第四个参数,msgtype, 是一个long int 类型,允许一个接收优先级形式的实现,如果msgtype的值为0,队列中第一个可用的消息就会被接收。如果其值大于0,具有相同消息类型的第一个消息就会被接收。如果其值小于0。第一个具有相同类型或是小于msgtype绝对值的消息就会被接收

第五个参数,msgflg,控制当没有合适类型的消息正在等待被接收时如何处理。如果在msgflg中设置了IPC_NOWAIT位,调用就会立即返回,而返回值为-1。如果msgflg标记中消除了IPC_NOWAIT位,进程就会被挂起,等待一个合适类型的消息到来

消息接收端:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>

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

#define MAX_TEXT 512
struct my_msg_st
{
long int my_msg_type;
char some_text[MAX_TEXT];
};

int main()
{
int running = 1;
int msgid;
struct my_msg_st some_data;
long int msg_to_receive = 0;

msgid = msgget((key_t)1234, 0666|IPC_CREAT);

if(msgid == -1)
{
fprintf(stderr, "msgget failed with error: %d\n", errno);
exit(EXIT_FAILURE);
}

while(running)
{
if(msgrcv(msgid, (void *)&some_data, MAX_TEXT, msg_to_receive, 0)==-1)
{
fprintf(stderr, "msgrcv failed with errno: %d\n", errno);
exit(EXIT_FAILURE);
}

printf("You wrote: %s", some_data.some_text);
if(strncmp(some_data.some_text, "end", 3)==0)
{
running = 0;
}
}

if(msgctl(msgid, IPC_RMID, 0)==-1)
{
fprintf(stderr, "msgctl(IPC_RMID) failed\n");
exit(EXIT_FAILURE);
}

exit(EXIT_SUCCESS);
}


消息发送端:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>

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

#define MAX_TEXT 512

struct my_msg_st
{
long int my_msg_type;
char some_text[MAX_TEXT];
};

int main()
{
int running = 1;
struct my_msg_st some_data;
int msgid;
char buffer[BUFSIZ];

msgid = msgget((key_t)1234, 0666|IPC_CREAT);

if(msgid == -1)
{
fprintf(stderr, "msgget failed with errno: %d\n", errno);
exit(EXIT_FAILURE);
}

while(running)
{
printf("Enter some text:");
fgets(buffer, BUFSIZ, stdin);
some_data.my_msg_type = 1;
strcpy(some_data.some_text, buffer);

if(msgsnd(msgid, (void *)&some_data, MAX_TEXT, 0)==-1)
{
fprintf(stderr, "msgsnd failed\n");
exit(EXIT_FAILURE);
}

if(strncmp(buffer, "end", 3)==0)
{
running = 0;
}

}

exit(EXIT_SUCCESS);
}


发送端和接收端谁先运行并无区别,就算发送端程序退出了,再运行接收端,同样能够得到发送过来的消息。因为消息已经发送到了消息队列中去了

[root@localhost xiaoxiduilie]# ./2

Enter some text:where are you

Enter some text:I miss you

Enter some text:wish you happy

Enter some text:end

[root@localhost xiaoxiduilie]# ./1

You wrote: where are you

You wrote: I miss you

You wrote: wish you happy

You wrote: end
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息