頭文件:
mqueue.h
庫:
rt--------librt.so
編譯的時候加-lrt
查看POSIX消息隊列所有函數:
man mq_overview
結構體:
struct mq_attr{
mq_flags;
——標誌:
————在mq_open創建時被初始化;
————在mq_setattr中設置;
————其值爲0(阻塞)或者O_NONBLOCK(非阻塞)。
mq_maxmsg;
——隊列的消息個數最大值:
————只能在mq_open創建時被初始化。
mq_msgsize;
——隊列中每個消息的最大值:
————只能在mq_open創建時被初始化。
mq_curmsgs:
——當前隊列的消息個數:
————在mq_getattr中獲得。
}
查看消息隊列文件:
創建的消息隊列在/dev/mqueue中存放。如果沒有需要建立一個。
建立方法:
依次輸入命令:
mkdir /dev/mqueue //創建文件夾
mount -t mqueue none /dev/mqueue//掛載
函數:
創建消息隊列:
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:
隊列屬性。爲上面所說的結構體。
返回值:
-1————出錯
其他———消息隊列描述符
代碼:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <mqueue.h>
#include <fcntl.h>
#include <sys/stat.h>
#define FILE_MODE (S_IWUSR|S_IRUSR|S_IRGRP|S_IROTH) //0644
int main(int argc,char* argv[]){
int c,flag=0;
long maxmsg = 10;
long msglen = 8192;
while((c=getopt(argc,argv,"q:l:"))!=-1){
switch(c){
case 'q':
maxmsg = atoi(optarg);
break;
case 'l':
msglen = atoi(optarg);
break;
}
}
if(optind != argc-1){
printf("usage:%s [-q <maxmsg>] [-l <msglen>] <mqname>\n",argv[0]);
return 1;
}
struct mq_attr attr;
attr.mq_maxmsg = maxmsg;
attr.mq_msgsize = msglen;
mqd_t mqd = mq_open(argv[optind],O_CREAT,FILE_MODE,&attr);
if(-1 == mqd){
perror("mq_open error");
return 1;
}
}
刪除消息隊列:
int mq_unlink(char* name);
參數:
name:
posix IPC名字。
返回值:
-1————出錯
0————成功
代碼:
#include <stdio.h>
#include <stdlib.h>
#include <mqueue.h>
#include <fcntl.h>
#include <sys/stat.h>
int main(){
mq_unlink("/tmp.test");
}
打開消息隊列:
mqd_t mq_open(const char* name, int oflag);
參數:
name:
posix IPC名字。
oflag:
標誌。(同創建中的oflag)
返回值:
-1————出錯
其他———描述符
關閉消息隊列:
int mq_close(mqd_t mqdes);
參數:
mqdes:
消息隊列描述符。
返回值:
-1——出錯
0——成功
設置消息隊列屬性:
int mq_getattr(mqd_t mqdes, struct mq_attr* nemattr, mq_attr* oldattr);
參數:
mqdes:
消息隊列描述符。
newattr:
新屬性;
只能設置mq_flags(0(阻塞)或O_NONBLOCK(非阻塞))。
oldattr:
舊屬性。
返回值:
-1——出錯
0——成功
代碼:
#include <stdio.h>
#include <stdlib.h>
#include <mqueue.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
int main(){
mqd_t mqd = mq_open("/tmp.test",O_RDWR);
if(-1 == mqd){
perror("mq_open error");
return;
}
struct mq_attr new_attr;
bzero(&new_attr,sizeof(new_attr));
//設置新屬性
new_attr.mq_flags = O_NONBLOCK;
struct mq_attr attr;
if(-1 == mq_setattr(mqd,&new_attr,&attr)){
perror("mq_setattr error");
return 1;
}
//輸出舊屬性
printf("flag:%ld,Max msg:%ld,Max msgsize:%ld,Cur msgnun:%ld\n",attr.mq_flags,attr.mq_maxmsg,attr.mq_msgsize,attr.mq_curmsgs);
}
獲取消息隊列屬性:
int mq_getattr(mqd_t mqdes, struct mq_attr* attr);
參數:
mqdes:
消息隊列描述符。
attr:
屬性。
返回值:
-1——出錯
0——成功
代碼:
#include <stdio.h>
#include <stdlib.h>
#include <mqueue.h>
#include <fcntl.h>
#include <sys/stat.h>
int main(int argc,char* argv[]){
mqd_t mqd = mq_open(argv[1],O_RDONLY);
if(-1 == mqd){
perror("mq_open error");
return;
}
struct mq_attr attr;
mq_getattr(mqd,&attr);
printf("flag:%ld,Max msg:%ld,Max msgsize:%ld,Cur msgnun:%ld\n",attr.mq_flags,attr.mq_maxmsg,attr.mq_msgsize,attr.mq_curmsgs);
}
發送消息:
int mq_send(mqd_t mqdes, const char* msg_ptr, size_t msg_len,unsigned msg_prio);
特點:
消息隊列已滿,mq_send()函數將阻塞,知道有可用空間再次允許放置消息。
如果O_NONBLOCK被指定,滿隊時mq_send()將不會阻塞,而是返回EAGAIN錯誤。
參數:
msg_ptr:
要發送消息的指針。
msg_len:
消息長度(不能大於屬性值mq_msgsize的值)。
msg_prio:
優先級(消息在隊列中將按照優先級從大到小的順序排列消息;數字越大優先級越高)。
代碼:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <mqueue.h>
#include <fcntl.h>
#include <string.h>
#include <sys/stat.h>
#define FILE_MODE (S_IWUSR|S_IRUSR|S_IRGRP|S_IROTH) //0644
int main(int argc,char* argv[]){
int c,flags=O_WRONLY;
while((c=getopt(argc,argv,"n"))!=-1){
switch(c){
case 'n':
flags|=O_NONBLOCK;//增加標誌屬性,現在爲只寫+非阻塞
break;
}
}
if(optind != argc-3){
printf("usage:%s [-n] <mqname> <message> <prio>\n");
return 1;
}
mqd_t mqd = mq_open(argv[optind],flags);
if(-1 == mqd){
perror("mq_open error");
return 1;
}
if(-1 == mq_send(mqd,argv[optind+1],strlen(argv[optind+1])+1,atoi(argv[optind+2]))){
perror("mq_send error");
return 1;
}
}
接收消息:
ssize_t mq_receive(mqd_t mqdes, char* msg_ptr, size_t msg_len,unsigned* msg_prio);
特點:
按優先級從高到低進行接收。即優先級值大的先接收。
如果隊列爲空,mq_receive()函數將阻塞,知道消息隊列中有新的消息。
如果O_NONBLOCK被指定,mq_receive()將不會阻塞,而是返回EAGAIN錯誤。
參數:
msg_ptr:
要接收消息的指針。
msg_len:
接收消息的長度(不能大於屬性值mq_msgsize的值)。
msg_prio:
接收到的優先級大小(消息在隊列中將按照優先級從大到小的順序排列消息;數字越大優先級越高)。
返回值:
-1————出錯
正數———接收到的消息長度
代碼:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <mqueue.h>
#include <fcntl.h>
#include <sys/stat.h>
#define FILE_MODE (S_IWUSR|S_IRUSR|S_IRGRP|S_IROTH) //0644
int main(int argc,char* argv[]){
int c,flags=O_RDONLY;
while((c=getopt(argc,argv,"n"))!=-1){
switch(c){
case 'n':
flags|=O_NONBLOCK;//增加標誌屬性,現在爲只讀|非阻塞
break;
}
}
if(optind != argc-1){
printf("usage:%s [-n] <mqname>\n");
return 1;
}
mqd_t mqd = mq_open(argv[optind],flags);
if(-1 == mqd){
perror("mq_open error");
return 1;
}
char buf[BUFSIZ];
int prio;
if(-1 == mq_receive(mqd,buf,BUFSIZ,&prio)){
perror("mq_send error");
return 1;
}
printf("msg:%s\nprio:%d\n",buf,prio);
}