System V IPC:消息队列

2020-02-26  本文已影响0人  FakeCSer爱去网吧

概念

API和涉及的数据结构

创建消息队列
#include <sys/msg.h>
int msgget(key_t key,int flag);

参数和返回值类比共享内存shmget

发送消息
#include <sys/msg.h>
int msgsnd(int msqid,void * ptr,size_t nbytes,int flag);

参数表:
msqid:消息队列ID
ptr:指向待发送的消息的指针
nbytes:消息的大小
flag:当消息队列满时如何处理(IPC_NOWAIT?)
返回值:
0:成功
-1:失败

struct mymsg
{
  long msgtype;
  char msgtext[MAXLENTH];
}
接收信息
#include <sys/msg.h>
int msgrcv(int msqid,void * ptr,size_t nbytes,long type,int flag);

参数表:
msqid:消息队列ID
ptr:指向待发送的消息的指针
nbytes:消息的大小
type:消息类型
flag:当消息队列满时如何处理(NOWAIT?)
返回值:
大于0:消息中数据部分的长度
-1:失败

type = 0时,返回队列中的第一个消息
type > 0时,返回队列中消息类型为type的第一个消息
type < 0时,返回消息队列中类型值小于或等于type的消息,若有多个,则返回最小的

注意数据大小要满足:消息队列定义的消息信息大小>=msgrcv中的数据大小>=msgsnd中的数据大小(即MAXLENTH>=msgrcv中nbytes>=msgsnd中的nbytes

消息队列操作
#include <sys/msg.h>
int msg(int msqid,int cmd,struct msqid_ds * buf);

参数表:
msqid:消息队列ID
cmd:待执行的操作
buf:存放消息队列属性的内存地址
返回值:
0:成功
-1:失败

示例代码

写端:创建消息队列,发送消息

#include <sys/msg.h>
#include <iostream>
#include <unistd.h>
#include <cstring>
#include <sys/ipc.h>
using namespace std;

#define MAXLENTH 128

struct msg_st
{
    int msg_type;
    char msg_text[MAXLENTH];
};

int main()
{

    int msg_id;
    int key = ftok(".",512);
    char buf[10];

    struct msg_st sndMsg;
    sndMsg.msg_type = 1;

    msg_id = msgget(key,IPC_CREAT|0666);
    if(msg_id == -1)
    {
        perror("msgget");
        exit(EXIT_FAILURE);
    }

    cin >> buf;
    strcpy(sndMsg.msg_text,buf);

    if(msgsnd(msg_id,(void *)&sndMsg,10,0)==-1)
    {
        perror("msgsnd");
        exit(EXIT_FAILURE);
    }
    sleep(10);
    return 0;
}

读端:接收信息,删除消息队列

#include <sys/msg.h>
#include <iostream>
#include <sys/ipc.h>
#include <cstring>
using namespace std;

#define MAXLENTH 128

struct msg_st
{
    int msg_type;
    char msg_text[MAXLENTH];
};

int main()
{

    int msg_id;
    int key = ftok(".",512);
    char buf[100];

    struct msg_st rcvMsg;

    msg_id = msgget(key,0666);
    if(msg_id == -1)
    {
        perror("msgget");
        exit(EXIT_FAILURE);
    }

    if(msgrcv(msg_id,(void *)&rcvMsg,20,0,0)==-1)
    {
        perror("msgrcv");
        exit(EXIT_FAILURE);
    }
    cout <<rcvMsg.msg_text <<endl;
    msgctl(msg_id,IPC_RMID,0);
    return 0;
}

上一篇下一篇

猜你喜欢

热点阅读