##消息隊列
比喻:回轉壽司、按優先級進行(讓列寧同志先走)
本質:內核鏈表
##POSIX消息隊列
接口
頭文件:mqueue.h
庫: rt librt.so real time
結構體: struct mq_attr
消息隊列屬性
mq_flags【標誌】:
在mq_open時被初始化;在mq_setattr設置;其值爲0或者O_NONBLOCK;
mq_maxmsg【隊列的消息個數最大值】:
只能在mq_open時被初始化
mq_msgsize【隊列每個消息的最大值】:
只能在mq_open時被初始化
mq_curmsgs【當前隊列消息長度】:
在mq_getattr獲取
函數【八大操作】
創建消息隊列:mqd_t mq_open(const char *name,int oflag,mode_t mode,struct mq_attr* attr);
name:posix IPC名字
oflag:標誌:O_CREAT【沒有該對象則創建】、O_EXCL【如果O_CREAT指定,但name不存在,就返回錯誤】、O_NONBLOCK【以非阻塞方式打開消息隊列】、O_RDONLY【只讀】、O_RDWR【讀寫】、O_WRONLY【只寫】
mode:權限:S_IWUSR【用戶/屬主寫】、S_IRUSR【用戶/屬主讀】、S_IWGRP【組成員寫】、S_IRGRP【組成員讀】、S_IWOTH【其他用戶寫】、S_IROTH【其他用戶讀】
attr:隊列屬性:【阻塞】attr.mq_flag = 0;【非阻塞】attr.mq_flag = NONBLOCK
返回值:-1【出錯】、其他【消息隊列描述符】
刪除消息隊列:int mq_unlink(const char* name);
name:posix IPC名字
返回值:-1【出錯】、0【成功】
打開消息隊列:mqd_t mq_open(const char* name,int oflag);
name:posix IPC名字
oflag:標誌:【只讀】O_RDONLY、【讀寫】O_RDWR、【只寫】O_WRONLY
返回值:-1【出錯】、其他【描述符】
關閉消息隊列:int mq_close(mqd_t mqdes,struct mq_attr,*newattr,struct mq_attr *oldattr);
mqdes:消息隊列描述符
newattr:新屬性;只設置mq_flags{0;NONBLOCK}
oldattr:舊屬性
返回值:-1【出錯】、0【成功】
獲取消息隊列屬性:int mq_getattr(mqd_t mqdes,struct mq_attr *attr);
mqdes:消息隊列描述符
attr:屬性
返回值:-1【出錯】、0【成功】
發送消息:int mq_send(mqd_t mqdes,const char *msg_ptr,size_t msg_len,unsigned msg_prio);
msg_ptr:消息的指針
msg_len:消息長度【不能大於屬性值mq_msgsize的值】
msg_prio:優先級【消息在隊列中將按照優先級大小順序來排列消息】
**消息隊列已滿,mq_send()函數將阻塞,直到有可用空間再次允許放置消息;如果O_NONBLOCK被指定,mq_send()那麼將不會阻塞,而是返回EAGAIN錯誤
接收消息:ssize_t mq_receive(mqd_t mqdes,char* msg_ptr,size_t msg_len,unsigned *msg_prio);
msg_ptr:消息的指針
msg_len:消息長度【不能大於屬性值mq_msgsize的值】
msg_prio:優先級【消息在隊列中將按照優先級大小順序來排列消息】
返回值:-1【出錯】、正數【接收到的消息長度】
**如果隊列空,mq_recieve()函數將阻塞,直到消息隊列中有新的消息;如果O_NONBLOCK被指定,mq_receive()那麼將不會阻塞,而是返回EAGAIN錯誤
查看
man mq_overview
ls /dev/mqueue
cat /dev/mqueue/PIC名字
##System V消息隊列
接口
頭文件:sys/msg.h
結構體:自定義消息緩衝區結構msgbuf
mtype【消息類型】:必須是long;必須是結構體第一個變量
mtext【消息數據】:可以隨意定義
函數
消息獲取:int msgget(key_t key,int msgflg)
key:IPC鍵
key_t ftok(char* path,int id)
path:地址
id:IP
IPC_PRIVATE:通常用於親緣進程
msgflg
IPC_CREAT【創建】
IPC_CREAT|IPC_EXCL
權限:可使用八進制數字
MSG_R【用戶讀】:0400
MSG_W【用戶寫】:0200
MSG_R>>3【組讀】:0040
MSG_W>>3【組寫】:0020
MSG_R>>6【其他讀】:0004
MSG_W>>6【其他寫】:0002
返回值:非負整數【消息隊列標識】、-1【失敗】
消息發送:int msgsnd(int msgid,const void* msgptr,size_t msgsz,int msgflg)
msgid:消息隊列標識
msgptr:消息結構體
一個長整型成員變量開始的結構體,消息結構體模板:
struct test_message{
long mtype;/*must>0*/
char mtext;/*data*/
};
msgsz【消息長度】:不包括長整型變量
msgflg【控制函數行爲】:0【忽略】、IPC_NOWAIT【如果消息隊列爲空,則返回一個ENOMSG,並將控制權交回調用函數的進程】、MSG_NOERROR【如果函數取得的消息長度大於msgsz,將只返回msgsz長度的信息,剩下的部分被丟棄了】、MSG_EXCEPT【當msgtype>0時接收類型不等於msgtype的第一條消息】
返回值:0【成功】、-1【失敗】
消息接受:int msgrcv(int msgid,void *msgptr,size_t msgsz,long int msgtype,int msgflg)
msggid【消息隊列標識】
msgptr【消息結構體】:以一個長整型成員變量開始的結構體
struct test_message{
long int message_type;
/*The data you wish to transfer*/
}
msgsz【消息長度】:不包括長整型變量
msgtype【接收類型】:0【獲取隊列中的第一個消息】、大於0【獲取具有相同消息類型的第一個信息】、小於0【獲取類型等於或小於msgtype的絕對值中最小的一個消息】
msgflg【控制函數行爲】:0【忽略】、IPC_NOWAIT【如果消息隊列爲空,則返回一個ENOMSG,並將控制權交回調用函數的進程】、MSG_NOERROR【如果函數取得的消息長度大於msgsz,將只返回msgsz長度的信息,剩下的部分被丟棄了】、MSG_EXCEPT【當msgtype>0時接收類型不等於msgtype的第一條消息】
返回值:非負整數【接受到的消息長度】、-1【失敗】
消息控制:int msggctl(int msgqid,int cmd,struct msqid_ds *buf)
msqid【消息隊列標識符】
cmd:IPC_STAT【獲取當前消息隊列控制信息】、IPC_SET【設置當前消息隊列控制信息】、IPC_RMID【刪除消息隊列】
buf【消息隊列模式結構】:msg_perm.mode【消息隊列讀寫模式】、msg_qbytes【隊列最大大小】、msg_cbytes【當前隊列大小】、msg_qnum【當前隊列消息數】
返回值:0【成功】、-1【失敗】
*實例:刪除消息 msgctl(msgqid,IPC_RM,NULL)
查看:ipcs