消息隊列操作函數

消息隊列操作函數

1、概述

  消息隊列可以認爲是一個消息鏈表,System V 消息隊列使用消息隊列標識符標識。具有足夠特權的任何進程都可以往一個隊列放置一個消息,具有足夠特權的任何進程都可以從一個給定隊列讀出一個消息。在某個進程往一個隊列寫入消息之前,並不需要另外某個進程在該隊列上等待消息的到達。System V 消息隊列是隨內核持續的,只有在內核重起或者顯示刪除一個消息隊列時,該消息隊列纔會真正被刪除。


對於系統中沒個消息隊列,內核維護一個msqid_ds的信息結構:

struct msqid_ds
  {
    struct msqid_ds {
    struct ipc_perm msg_perm;
    struct msg *msg_first;      /* first message on queue,unused  */
    struct msg *msg_last;       /* last message in queue,unused */
    __kernel_time_t msg_stime;  /* last msgsnd time */
    __kernel_time_t msg_rtime;  /* last msgrcv time */
    __kernel_time_t msg_ctime;  /* last change time */
    unsigned long  msg_lcbytes; /* Reuse junk fields for 32 bit */
    unsigned long  msg_lqbytes; /* ditto */
    unsigned short msg_cbytes;  /* current number of bytes on queue */
    unsigned short msg_qnum;    /* number of messages in queue */
    unsigned short msg_qbytes;  /* max number of bytes on queue */
    __kernel_ipc_pid_t msg_lspid;   /* pid of last msgsnd */
    __kernel_ipc_pid_t msg_lrpid;   /* last receive pid */
};

2、System V 消息隊列操作函數

系統V消息隊列API共有四個,使用時需要包括幾個頭文件:

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/msg.h>

 1)int msgget(key_t key, int msgflg)

參數key是一個鍵值,由ftok獲得;msgflg參數是一些標誌位。該調用返回與健值key相對應的消息隊列描述字。

在以下兩種情況下,該調用將創建一個新的消息隊列:

    如果沒有消息隊列與健值key相對應,並且msgflg中包含了IPC_CREAT標誌位;
    key參數爲IPC_PRIVATE;

 參數msgflg可以爲以下:IPC_CREAT、IPC_EXCL、IPC_NOWAIT或三者的或結果。

調用返回:成功返回消息隊列描述字,否則返回-1。

注:參數key設置成常數IPC_PRIVATE並不意味着其他進程不能訪問該消息隊列,只意味着即將創建新的消息隊列。

2)int msgrcv(int msqid, struct msgbuf *msgp, int msgsz, long msgtyp, int msgflg);
該系統調用從msgid代表的消息隊列中讀取一個消息,並把消息存儲在msgp指向的msgbuf結構中。

msqid爲消息隊列描述字;消息返回後存儲在msgp指向的地址,msgsz指定msgbuf的mtext成員的長度(即消息內容的長度),msgtyp爲請求讀取的消息類型;讀消息標誌msgflg可以爲以下幾個常值的或:

    IPC_NOWAIT 如果沒有滿足條件的消息,調用立即返回,此時,errno=ENOMSG
    IPC_EXCEPT 與msgtyp>0配合使用,返回隊列中第一個類型不爲msgtyp的消息
    IPC_NOERROR 如果隊列中滿足條件的消息內容大於所請求的msgsz字節,則把該消息截斷,截斷部分將丟失。

 msgrcv手冊中詳細給出了消息類型取不同值時(>0; <0; =0),調用將返回消息隊列中的哪個消息。

msgrcv()解除阻塞的條件有三個:

    消息隊列中有了滿足條件的消息;
    msqid代表的消息隊列被刪除;
    調用msgrcv()的進程被信號中斷;

 調用返回:成功返回讀出消息的實際字節數,否則返回-1。

3)int msgsnd(int msqid, struct msgbuf *msgp, int msgsz, int msgflg);
向msgid代表的消息隊列發送一個消息,即將發送的消息存儲在msgp指向的msgbuf結構中,消息的大小由msgze指定。

對發送消息來說,有意義的msgflg標誌爲IPC_NOWAIT,指明在消息隊列沒有足夠空間容納要發送的消息時,msgsnd是否等待。造成msgsnd()等待的條件有兩種:

    當前消息的大小與當前消息隊列中的字節數之和超過了消息隊列的總容量;
    當前消息隊列的消息數(單位"個")不小於消息隊列的總容量(單位"字節數"),此時,雖然消息隊列中的消息數目很多,但基本上都只有一個字節。

msgsnd()解除阻塞的條件有三個:

    不滿足上述兩個條件,即消息隊列中有容納該消息的空間;
    msqid代表的消息隊列被刪除;
    調用msgsnd()的進程被信號中斷;

 調用返回:成功返回0,否則返回-1。

4)int msgctl(int msqid, int cmd, struct msqid_ds *buf);
該系統調用對由msqid標識的消息隊列執行cmd操作,共有三種cmd操作:IPC_STAT、IPC_SET 、IPC_RMID。

    IPC_STAT:該命令用來獲取消息隊列信息,返回的信息存貯在buf指向的msqid結構中;
    IPC_SET:該命令用來設置消息隊列的屬性,要設置的屬性存儲在buf指向的msqid結構中;可設置屬性包括:msg_perm.uid、msg_perm.gid、msg_perm.mode以及msg_qbytes,同時,也影響msg_ctime成員。
    IPC_RMID:刪除msqid標識的消息隊列;

 調用返回:成功返回0,否則返回-1。






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章