POSIX消息隊列(mq_)

頭文件:

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);
}


發佈了93 篇原創文章 · 獲贊 44 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章