天天看點

System V消息隊列(2)

msgsnd函數

功能:把一條消息添加到消息隊列中

原型

int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);

參數

msgid: 由msgget函數傳回的消息隊列辨別碼

msgp:是一個指針,指針指向準備發送的消息,

msgsz:是msgp指向的消息長度,這個長度不含儲存消息類型的那個long int長整型

msgflg:控制着目前消息隊列滿或到達系統上限時将要發生的事情

傳回值:成功傳回0;失敗傳回-1

msgflg=IPC_NOWAIT表示隊列滿不等待,傳回EAGAIN錯誤。

消息結構在兩方面受到制約。首先,它必須小于系統規定的上限值;其次,它必須以一個long int長整數開始,接收者函數将利用這個長整數确定消息的類型

消息結構參考形式如下:

struct msgbuf {

long  mtype;

char mtext[1];

}

msgrcv函數

功能:是從一個消息隊列接收消息

ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);

msgp:是一個指針,指針指向準備接收的消息,

msgtype:它可以實作接收優先級的簡單形式

msgflg:控制着隊列中沒有相應類型的消息可供接收時将要發生的事

傳回值:成功傳回實際放到接收緩沖區裡去的字元個數,失敗傳回-1

msgtype=0傳回隊列第一條資訊

msgtype>0傳回隊列第一條類型等于msgtype的消息 

msgtype<0傳回隊列第一條類型小于等于msgtype絕對值的消息,并且是滿足條件的消息類型最小的消息

msgflg=IPC_NOWAIT,隊列沒有可讀消息不等待,傳回ENOMSG錯誤。

msgflg=MSG_NOERROR,消息大小超過msgsz時被截斷

msgtype>0且msgflg=MSG_EXCEPT,接收類型不等于msgtype的第一條消息。

msg_send.c

#include <unistd.h>

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/msg.h>

#include <stdlib.h>

#include <stdio.h>

#include <errno.h>

#define ERR_EXIT(m) \

        do \

        { \

                perror(m); \

                exit(EXIT_FAILURE); \

        } while(0)

    long mtype;       /* message type, must be > 0 */

    char mtext[1];    /* message data */

};

int main(int argc, char *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");

    struct msgbuf *ptr;

    ptr = (struct msgbuf*)malloc(sizeof(long) + len);

    ptr->mtype = type;

    if (msgsnd(msgid, ptr, len, IPC_NOWAIT) < 0)

        ERR_EXIT("msgsnd");

    return 0;

msg_recv.c

#define MSGMAX 8192

    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‘:

            /*printf("AAAA\n");*/

            flag |= IPC_NOWAIT;

        case ‘t‘:

            /*

            printf("BBBB\n");

            int n = atoi(optarg);

            printf("n=%d\n", n);

            */

            type = atoi(optarg);

        }

    ptr = (struct msgbuf*)malloc(sizeof(long) + MSGMAX);

    int n = 0;

    if ((n = msgrcv(msgid, ptr, MSGMAX, type, flag)) < 0)

    printf("read %d bytes type=%ld\n", n, ptr->mtype);