第二十六章 system v消息队列(二)

msgsnd

int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
作用:
    把一条消息添加到消息队列中
参数:
    msqid : 由msgget函数返回的消息队列标识
    msgp :是一个指针,指针指向准备发送的消息  
    msgsz :是msgp指向的消息长度,这个长度不含保存消息类型的那个long int长整型  
    msgflg :控制着当前消息队列或到达系统上限时将要发生的事情
        IPC_NOWAIT表示队列满不等待,返回EAGAIN错误
        0 表示队列满阻塞
            
            
返回值:
    成功 : 0
    失败 : -1

msgbuf

  消息结构在两方面受制约:

  • 它必须小于系统规定的上限值(MSGMAX)
  • 它必须以一个long int长整数开始,接收者函数将利用这个长整数确定消息的类型
struct msgbuf {
    long mtype;       /* message type, must be > 0 */
    char mtext[1];    /* message data */
};
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

#define ERR_EXIT(m)         \
    do                      \
    {                       \
        perror(m);          \
        exit(EXIT_FAILURE); \
    } while (0)

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

int main(int argc, char const *argv[])
{

    if(argc != 3)
    {
        fprintf(stderr, "Usage : %s <bytes> <type>\n",argv[0]);
        exit(EXIT_FAILURE);
    }

    int len = atoi(argv[1]);
    int type = atoi(argv[2]);

    int msgid;
    msgid = msgget(1234,0);
    if(msgid == -1)
        ERR_EXIT("msgget");

    printf("msget success, msgid=%d\n!",msgid); 

    struct msgbuf* ptr;
    ptr = (struct msgbuf*)malloc(sizeof(long)+len);
    ptr->mtype = type;

    // =MSGMNB 阻塞  
    // >MSGMNB Invalid argument
    // if(msgsnd(msgid, ptr, len, 0) < 0)

    // =MSGMNB Resource temporarily unavailable  
    // >MSGMNB Invalid argument
    if(msgsnd(msgid, ptr, len, IPC_NOWAIT) < 0)
        ERR_EXIT("msgsnd");
    
    free(ptr);
    return 0;
}

msgrcv

ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
作用:
    从消息队列接受消息
参数:
    msqid : 由msgget函数返回的消息队列标识
    msgp :是一个指针,指针指向准备接收的消息  
    msgsz :是msgp指向的消息长度,这个长度不含保存消息类型的那个long int长整型
    msgtyp :它可以实现接收优先级的简单形式
        =0 : 返回队列第一条消息
        >0 : 返回队列第一条类型等于msgtype的消息
        <0 : 返回队列第一条类型小于等于msgtype绝对值的消息
        >0 && msgflg=MSC_EXCEPT 接收类型不等于msgtype的第一条消息
        
    msgflg :控制着队列中没有相应类型的消息可提供接收时将要发生的事 
        IPC_NOWAIT表示队列满不等待,返回EAGAIN错误
        MSG_NOERROR 消息大小超过msgsz时被截断
        0 表示队列满阻塞
返回值:
    成功 : 返回实际放到接收缓冲区里的字符个数
    失败 : -1
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

#define ERR_EXIT(m)         \
    do                      \
    {                       \
        perror(m);          \
        exit(EXIT_FAILURE); \
    } while (0)

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

#define MSGMAX 8192
int main(int argc, char* argv[])
{

    int flag = 0;
    int type = 0;
    int opt;

    while(1)
    {
        opt = getopt(argc, argv, "nt:");
        if(opt == '?')
            exit(EXIT_FAILURE);

        if(opt == -1)
            break;
        switch (opt)
        {
        case 'n':
            flag |= IPC_NOWAIT;
            break;
        case 't':
            type = atoi(optarg);
            break;
        }
    }

    int msgid;
    msgid = msgget(1234,0);
    if(msgid == -1)
        ERR_EXIT("msgget");

    printf("msget success, msgid=%d\n",msgid); 

    struct msgbuf* ptr;
    ptr = (struct msgbuf*)malloc(sizeof(long) + MSGMAX);
    ptr->mtype = type;

    int nRec = 0;
    if( (nRec = msgrcv(msgid, ptr, MSGMAX, type, flag)) < 0)
        ERR_EXIT("msgsnd");
    
    printf("read %d bytes type = %ld\n", nRec, ptr->mtype);
    free(ptr);
    return 0;
}
posted @ 2019-09-24 13:48  sfdevs  阅读(147)  评论(0编辑  收藏  举报