先給出建立消息隊列的程序:shell
#include <stdio.h> #include <stdlib.h> #include <mqueue.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <fcntl.h> #include <errno.h> #define MQ_NAME ("/tmp") #define MQ_FLAG (O_RDWR | O_CREAT | O_EXCL) // 建立MQ的flag #define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) // 設定建立MQ的權限 int main() { mqd_t posixmq; int rc = 0; struct mq_attr mqattr; mqattr.mq_maxmsg = 3; mqattr.mq_msgsize = 1024; posixmq = mq_open(MQ_NAME, MQ_FLAG, FILE_MODE, &mqattr); // 建立只可存放三條消息的消息隊列 if(-1 == posixmq) { perror("建立MQ失敗"); exit(1); } rc = mq_close(posixmq); if(0 != rc) { perror("關閉失敗"); exit(1); } #if 0 rc = mq_unlink(MQ_NAME); if(0 != rc) { perror("刪除失敗"); exit(1); } #endif return 0; }
編譯並執行:
[infor@s123 PosixMq]$ gcc -o createmq createmq.c -lrt [infor@s123 PosixMq]$ ./createmq
最後程序並無刪除消息隊列(消息隊列有隨內核持續性),如再次執行該程序則會給出錯誤信息:
[infor@s123 PosixMq]$ ./createmq 建立MQ失敗: File exists
消息隊列的讀寫主要使用下面兩個函數:
#include <mqueue.h> /* 返回:若成功則爲0, 若出錯則爲-1 */ ssize_t mq_receive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned *msg_prio); /* 返回:若成功則爲消息中字節數,若出錯則爲-1 */ int mq_send(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned msg_prio);
下面給出向消息隊列寫消息的程序:
#include <stdio.h> #include <stdlib.h> #include <mqueue.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <fcntl.h> #include <errno.h> /*向消息隊列發送消息,消息隊列名及發送的信息經過參數傳遞*/ int main(int argc, char *argv[]) { mqd_t mqd; char *ptr; size_t len; unsigned int prio; int rc; if(argc != 4) { printf("Usage: sendmq <name> <bytes> <priority>\n"); exit(1); } len = atoi(argv[2]); prio = atoi(argv[3]); //只寫模式找開消息隊列 mqd = mq_open(argv[1], O_WRONLY); if(-1 == mqd) { perror("打開消息隊列失敗"); exit(1); } // 動態申請一塊內存 ptr = (char *) calloc(len, sizeof(char)); if(NULL == ptr) { perror("申請內存失敗"); mq_close(mqd); exit(1); } /*向消息隊列寫入消息,如消息隊列滿則阻塞,直到消息隊列有空閒時再寫入*/ rc = mq_send(mqd, ptr, len, prio); if(rc < 0) { perror("寫入消息隊列失敗"); mq_close(mqd); exit(1); } // 釋放內存 free(ptr); return 0; }
編譯並執行:
[infor@s123 PosixMq]$ gcc -o sendmq sendmq.c -lrt [infor@s123 PosixMq]$ ./sendmq /tmp 30 15 [infor@s123 PosixMq]$ ./sendmq /tmp 30 16 [infor@s123 PosixMq]$ ./sendmq /tmp 30 17 [infor@s123 PosixMq]$ ./sendmq /tmp 30 18
上面前後向消息隊列「/tmp」寫入了四條消息,由於先前建立的消息隊列只容許存放3條消息,本次第四次寫入時程序會阻塞。直到有另外進程從消息隊列取走消息後本次寫入才成功返回。函數
下面經過程序讀消息隊列:spa
#include <stdio.h> #include <stdlib.h> #include <mqueue.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <fcntl.h> #include <errno.h> /*讀取某消息隊列,消息隊列名經過參數傳遞*/ int main(int argc, char *argv[]) { mqd_t mqd; struct mq_attr attr; char *ptr; unsigned int prio; size_t n; int rc; if(argc != 2) { printf("Usage: readmq <name>\n"); exit(1); } /*只讀模式打開消息隊列*/ mqd = mq_open(argv[1], O_RDONLY); if(mqd < 0) { perror("打開消息隊列失敗"); exit(1); } // 取得消息隊列屬性,根據mq_msgsize動態申請內存 rc = mq_getattr(mqd, &attr); if(rc < 0) { perror("取得消息隊列屬性失敗"); exit(1); } /*動態申請保證能存放單條消息的內存*/ ptr = calloc(attr.mq_msgsize, sizeof(char)); if(NULL == ptr) { printf("動態申請內存失敗\n"); mq_close(mqd); exit(1); } /*接收一條消息*/ n = mq_receive(mqd, ptr, attr.mq_msgsize, &prio); if(n < 0) { perror("讀取失敗"); mq_close(mqd); free(ptr); exit(1); } printf("讀取 %ld 字節\n 優先級爲 %u\n", (long)n, prio); return 0; }
編譯並執行:
[infor@s123 PosixMq]$ ./readmq /tmp 讀取 30 字節 優先級爲 17 [infor@s123 PosixMq]$ ./readmq /tmp 讀取 30 字節 優先級爲 18 [infor@s123 PosixMq]$ ./readmq /tmp 讀取 30 字節 優先級爲 16 [infor@s123 PosixMq]$ ./readmq /tmp 讀取 30 字節 優先級爲 15 [infor@s123 PosixMq]$ ./readmq /tmp
程序執行五次,第一次執行完,先前阻塞在寫處的程序成功返回。第五次執行,由於消息隊列已經爲空,程序阻塞。直到另外的進程向消息隊列寫入一條消息。
另外,還能夠看出Posix消息隊列每次讀出的都是消息隊列中優先級最高的消息。code
2011-11-17 任洪彩 qdurenhongcai@163.com隊列
轉載請註明出處。進程