消息隊列

一、Posix消息隊列

​1、mq_open,mq_close,mq_unlink

 #include <mqueue.h>

mqd_t mq_open(const char *name, int oflag, ...);

oflag:O_RDONLY​,O_WRONLY,O_RDWR,O_CREAT,O_EXCL,O_NONBLOCK

mq_open的返回值爲消息隊列描述符,消息隊列的名字只能以一個'/'開頭,名字中不能包含其他的'/'。

#include <mqueue.h>

int mq_close(mqd_t mqdes);

​一個進程終止時他所打開的消息隊列都會關閉,關閉消息隊列之後,消息隊列並不在系統中刪除。

要從系統中刪除需要調用mq_unlink

#include <mqueue.h>

int mq_unlink(const char *name);

name爲​mq_open的第一個參數。

每個消息隊列保存着當前打開的描述符的引用計數器,當引用計數大於0時name能夠刪除但是消息隊列的析構要等到最後一個mq_close發生才進行。

2、mq_getattr、mq_setattr



​3、mq_send、mq_receive


​mq_receive的len不能小於隊列中消息的最大大小,小於該值mq_receive會立即返回EMSGSIZE錯誤。

​mq_send的prio參數是待發送消息的優先級,其值必須小於MQ_PRIO_MAX,數值越大,優先級越高。 POSIX 消息隊列在調用 mq_receive 時總是返回隊列中最高優先級的最早消息。如果消息不需要設定優先級,那麼可以在 mq_send是置msg_prio爲0,mq_receive 的 msg_prio 置爲 NULL。如果mq_receive的priop指針非空,則返回消息的優先級通過該指針存放。

4、消息隊列的限制

mq_mqxmsg隊列中最大消息數。

mq_msgsize給定消息的最大字節數。

MQ_OPEN_MAX一個進程能夠擁有同時打開消息隊列的最大數目​

MQ_PRIO_MAX任意消息的最大優先級加1

5、mq_notify

​Posix消息隊列容許異步事件通知,以告知何時有一個消息放置到某個空消息隊列中,這種通知有兩種方式可以選擇:

  • (1)產生一個信號
  • (2)創建一個線程來執行一個指定的函數

這種通知通過調用mq_notify建立

#include 
int mq_notify(mqd_t mqdes, const struct sigevent* notification);

該函數爲指定隊列建立或刪除異步事件通知

(1).如果notification參數爲非空,那麼當前進程希望在有一個消息到達所指定的先前爲空的對列時得到通知。

(2).如果notification參數爲空,而且當前進程被註冊爲接收指定隊列的通知,那麼已存在的註冊將被撤銷。

(3).任意時刻只有一個進程可以被註冊爲接收某個給定隊列的通知。

(4).當有一個消息到達先前爲空的消息隊列,而且已有一個進程被註冊爲接收該隊列的通知時,只有在沒有任何線程阻塞在該隊列的mq_receive調用中的前提下,通知纔會發出。即說明,在mq_receive調用中的阻塞比任何通知的註冊都優先。

(5).當前通知被髮送給它的註冊進程時,其註冊會被撤銷。該進程必須再次調用mq_notify以重新註冊。

union sigval{
int     sival_int;          
void    *sival_ptr;         
};

struct sigevent{
int     sigev_notify;       
int     sigev_signo;        

union sigval    sigev_value;

void    (*sigev_notify_function)(union sigval);
pthread_attr_t  *sigev_notify_attributes;


};

二、System V消息隊列

ftok()

#include 

#include 

函數原型:

 key_t  ftok( const  char * pathname , int   proj_id  );

參數:

 pathname 就時你指定的文件名(該文件必須是存在而且可以訪問的),id是子序號,雖         然爲int,但是隻有8個比特被使用(0-255)。

返回值: 成功時候返回key_t 類型的key值,失敗返回-1

msgget

#include 

#include 

#include 

函數原型: int    msgget ( key_t  key , int  msgflg );

函數描述:建立消息隊列

參數:

msgget()函數的第一個參數是消息隊列對象的關鍵字(key),函數將它與已有的消息隊列對象的關鍵字進行比較來判斷消息隊列對象是否已經創建。而函數進行的具體操作是由第二個參數,msgflg 控制的。它可以取下面的幾個值:IPC_CREAT :如果消息隊列對象不存在,則創建之,否則則進行打開操作;IPC_EXCL:和IPC_CREAT 一起使用(用”|”連接),如果消息對象不存在則創建之,否     則產生一個錯誤並返回。

返回值:

成功時返回隊列ID,失敗返回-1,錯誤原因存於error中

EEXIST (Queue exists, cannot create)EIDRM (Queue is marked for deletion)ENOENT (Queue does not exist)ENOMEM (Not enough memory to create queue)ENOSPC (Maximum queue limit exceeded)

msgsnd函數:將消息送入消息隊列

#include 

#include 

#include 

函數原型:int  msgsnd ( int msgid ,  struct msgbuf*msgp , int msgsz, int msgflg );

參數說明:

傳給msgsnd()函數的第一個參數msqid 是消息隊列對象的標識符(由msgget()函數得

到),第二個參數msgp 指向要發送的消息所在的內存,第三個參數msgsz 是要發送信息     的長度(字節數),可以用以下的公式計算:msgsz = sizeof(struct mymsgbuf) - sizeof(long);第四個參數是控制函數行爲的標誌,可以取以下的值:0,忽略標誌位;IPC_NOWAIT,如果消息隊列已滿,消息將不被寫入隊列,控制權返回調用函數的線程。如果不指定這個參數,線程將被阻塞直到消息被可以被寫入。

smgbuf結構體定義如下:

struct smgbuf

{

                     long   mtype;

                    char   mtext [x] ;  //長度由msgsz決定

}

msgflg 可設置爲 IPC_NOWAIT 。如果消息隊列已滿或其他情況無法送入消息,則立即 返回 EAGIN

返回: 0 on success

-1 on error: errno = EAGAIN (queue is full, and IPC_NOWAIT was asserted)EACCES (permission denied, no write permission)EFAULT (msgp address isn't accessable – invalid)EIDRM (The message queue has been removed)EINTR (Received a signal while waiting to write)EINVAL (Invalid message queue identifier, nonpositivemessage type, or invalid message size)ENOMEM (Not enough memory to copy message buffer)

msgrcv函數:從消息隊列中讀取消息

#include 

#include 

#include 

函數定義:int  msgrcv( int  msgid , struct   msgbuf*  msgp ,  int msgsz ,  long msgtyp, int msgflg);

參數:

函數的前三個參數和msgsnd()函數中對應的參數的含義是相同的。第四個參數mtype

指定了函數從隊列中所取的消息的類型。函數將從隊列中搜索類型與之匹配的消息並將之返回。不過這裏有一個例外。如果mtype 的值是零的話,函數將不做類型檢查而自動返     回隊列中的最舊的消息。第五個參數依然是是控制函數行爲的標誌,取值可以是:0,表示忽略;IPC_NOWAIT,如果消息隊列爲空,則返回一個ENOMSG,並將控制權交回調用函數的進程。如果不指定這個參數,那麼進程將被阻塞直到函數可以從隊列中得到符合條件的消息爲止。如果一個client 正在等待消息的時候隊列被刪除,EIDRM 就會被返回。如果     進程在阻塞等待過程中收到了系統的中斷信號,EINTR 就會被返回。MSG_NOERROR,如果函數取得的消息長度大於msgsz,將只返回msgsz 長度的信息,剩下的部分被丟棄了。如果不指定這個參數,E2BIG 將被返回,而消息則留在隊列中不     被取出。當消息從隊列內取出後,相應的消息就從隊列中刪除了。

msgbuf:結構體,定義如下:

struct msgbuf

{

                      long  mtype ;  //信息種類

                       char   mtest[x];//信息內容   ,長度由msgsz指定

}

msgtyp:  信息類型。 取值如下:

 msgtyp = 0 ,不分類型,直接返回消息隊列中的第一項

 msgtyp > 0 ,返回第一項 msgtyp與 msgbuf結構體中的mtype相同的信息

msgtyp <0 , 返回第一項 mtype小於等於msgtyp絕對值的信息

msgflg:取值如下:

IPC_NOWAIT ,不阻塞

IPC_NOERROR ,若信息長度超過參數msgsz,則截斷信息而不報錯。

返回值:

成功時返回所獲取信息的長度,失敗返回-1,錯誤信息存於error
發佈了43 篇原創文章 · 獲贊 6 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章