您的位置:首页 > 其它

进程通信之消息队列

2017-01-03 21:40 351 查看
1、消息队列就是一个消息的链表。可以把消息看作一个记录,具有特定的格式以及特定的优先级

2、 对消息队列有写权限的进程可以向其中按照一定的规则添加新消息;对消息队列有读权限的进程则可以从消息队列中读走消息。

3、man 2 msgrcv

4、函数int msgget(key_t key, int msgflg)

–参数“key”:消息队列关联的标识符 key = IPC_PRIVATV = 0

–参数“msgflg”:消息队列的建立标志和存取权限。IPC_CREAT 如果内核中没有此队列则创建它;IPC_EXCL 当 和IPC_CREAT 一起使用时,如果队列已经存在,则失败。

–返回值:执行成功则返回消息队列的标识符,否则返回-1。

5、 #include <sys/types.h>

#include <sys/ipc.h>

#include <sys/msg.h>

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

msqid:为指定的要操作的队列

cmd:参数指定所要进行的操作,其中有些操作需要buf参数。

IPC_STAT

IPC_SET

IPC_RMID //删除消息队列

struct msqid_ds {
struct ipc_perm msg_perm;     /* Ownership and permissions */
time_t          msg_stime;    /* Time of last msgsnd(2) */
time_t          msg_rtime;    /* Time of last msgrcv(2) */
time_t          msg_ctime;    /* Time of last change */
unsigned long   __msg_cbytes; /* Current number of bytes in
queue (nonstandard) */
msgqnum_t       msg_qnum;     /* Current number of messages
in queue */
msglen_t        msg_qbytes;   /* Maximum number of bytes
allowed in queue */
pid_t           msg_lspid;    /* PID of last msgsnd(2) */
pid_t           msg_lrpid;    /* PID of last msgrcv(2) */
};

The ipc_perm structure is defined as follows (the highlighted fields are settable using IPC_SET):

struct ipc_perm {
key_t          __key;       /* Key supplied to msgget(2) */
uid_t          uid;         /* Effective UID of owner */
gid_t          gid;         /* Effective GID of owner */
uid_t          cuid;        /* Effective UID of creator */
gid_t          cgid;        /* Effective GID of creator */
unsigned short mode;        /* Permissions */
unsigned short __seq;       /* Sequence number */
};


6、函数ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg)
–参数msqid:消息队列的标识码

–参数*msgp:指向消息缓冲区的指针

–参数msgsz:消息的长短

–参数msgtyp

• msgtyp等于0 ,则返回队列的最早的一个消息

• msgtyp大于0,则返回其类型为mtype的第一个消息

• msgtyp小于0,则返回其类型小于或等于mtype参数的绝对值的最小的一个消息

–参数msgflg:标志位为0,则表示忽略

–返回值:成功返回数据长度,错误返回-1

7、函数int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg)

–参数msqid:消息队列的标识码

–参数*msgp:指向消息缓冲区的指针,此位置用来暂时存储发送和接收的消息,是一个用户可定义的通用结构

–参数msgsz:消息的长短

–参数msgflg:标志位

–返回值:成功返回0,错误返回-1

结构体msgp,是一个标准的通用结构

struct msgbuf {
long mtype;       /* message type, must be > 0 */
char mtext[nbyte];    /* message data */
};


例:

msgsend.c

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/msg.h>
#include <errno.h>

#define MAX_TEXT 512
struct msg_st
{
long int msg_type;
char text[MAX_TEXT];
};

int main()
{
int running = 1;
struct msg_st data;
char buffer[BUFSIZ];
int msgid = -1;

//建立消息队列
msgid = msgget((key_t)1234, 0666 | IPC_CREAT);
if(msgid == -1)
{
fprintf(stderr, "msgget failed with error: %d\n", errno);
exit(EXIT_FAILURE);
}

//向消息队列中写消息,直到写入end
while(running)
{
//输入数据
printf("Enter some text: ");
fgets(buffer, BUFSIZ, stdin);
data.msg_type = 1;    //注意2
strcpy(data.text, buffer);
//向队列发送数据
if(msgsnd(msgid, (void*)&data, MAX_TEXT, 0) == -1)
{
fprintf(stderr, "msgsnd failed\n");
exit(EXIT_FAILURE);
}
//输入end结束输入
if(strncmp(buffer, "end", 3) == 0)
running = 0;
sleep(1);
}
exit(EXIT_SUCCESS);
}


msgreceive.c

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/msg.h>

struct msg_st
{
long int msg_type;
char text[BUFSIZ];
};

int main()
{    int running = 1;
int msgid = -1;
struct msg_st data;
long int msgtype = 0; //注意1

//建立消息队列
msgid = msgget((key_t)1234, 0666 | IPC_CREAT);
if(msgid == -1)
{
fprintf(stderr, "msgget failed with error: %d\n", errno);
exit(EXIT_FAILURE);
}
//从队列中获取消息,直到遇到end消息为止
while(running)
{
if(msgrcv(msgid, (void*)&data, BUFSIZ, msgtype, 0) == -1)
{
fprintf(stderr, "msgrcv failed with errno: %d\n", errno);
exit(EXIT_FAILURE);
}
printf("You wrote: %s\n",data.text);
//遇到end结束
if(strncmp(data.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);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: