###概念###
訊息佇列就是乙個訊息的鍊錶。可以把訊息看作乙個記錄,具有特定的格式以及特定的優先順序。對訊息佇列有寫許可權的程序
可以向其中按照一定的規則新增新訊息;對訊息佇列有讀許可權的程序則可以從訊息佇列中讀走訊息。
訊息佇列是乙個存放在核心中的訊息鍊錶,每個訊息佇列由訊息佇列識別符號標識。與管道不同的是訊息佇列存放在核心中,
只有在核心重啟(即作業系統重啟)或者顯式地刪除乙個訊息佇列時,該訊息佇列才會被真正刪除。
###標頭檔案###
#include
#include
#include
###資料結構###
1.訊息緩衝結構 (傳送、接收訊息都要以這個 資料結構模板
進行)struct
msgstru;
說明:訊息文字可以為任意型別,由使用者根據需要定義,如字元陣列、結構體等;
訊息佇列中的訊息的大小是受限制的,在核心中存在巨集定義。
2、msqid_ds -核心資料結構
linux核心中,每個訊息佇列都維護乙個結構體msqid_ds ,此結構體儲存著訊息佇列當前的狀態資訊。
struct msqid_ds ;
各個欄位的含義:
msg_perm:是乙個ipc_perm(定義在標頭檔案sys/ipc.h)的結構,儲存了訊息佇列的訪問許可權,以及佇列的使用者id、組id等資訊。
msg_first:指向佇列中的第一條訊息
msg_last:指向佇列中的最後一條訊息
msg_stime:向訊息佇列傳送最後一條資訊的時間
msg_rtime:從訊息佇列取最後一條訊息的時間
msg_ctime:最後一次變更訊息佇列的時間
msg_lcbytes:訊息佇列中所有訊息佔的位元組數
msg_qnum:訊息佇列中的訊息數目
msg_qbytes:訊息佇列的最大位元組數
msg_lspid:向訊息佇列傳送最後一條訊息的程序id
msg_lrpid:從訊息佇列讀取最後一條訊息的程序id
3、ipc_perm -核心資料結構
結構體ipc_perm儲存著訊息佇列的一些重要的資訊,比如訊息佇列關聯的鍵值,訊息佇列的使用者id,組id等。
定義在sys/ipc.h中。
struct ipc_perm
;幾個主要欄位的含義如下:
key:建立訊息佇列用到的鍵值key
uid:訊息佇列的使用者id
gid:訊息佇列的組id
cuid:建立訊息佇列的程序使用者id
cgid:建立訊息佇列程序組id
###常用介面函式###
1. 判斷訊息列隊是否存在 存在返回訊息列隊msqid,否則返回負值
int msqid =
msgget(msgkey,ipc_excl); //通過key鍵msgkey(整數)與msqid關聯
2.建立訊息列隊 成功返回訊息列隊msqid,否則返回負值
int msqid =
msgget(msgkey,ipc_creat|
0666);
/*建立訊息列隊*/ //許可權讀寫
3.傳送訊息 傳送失敗返回負值
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msg***);
//msqid:訊息佇列的標識碼
//msgp:指向訊息緩衝區的指標,此位置用來暫時儲存傳送和接收的訊息,結構由使用者根據訊息模板自行定義
//msgsz:訊息的大小
//msg***:用來指明核心程式在佇列滿了的情況下所應採取的行動。如果msg***為常數ipc_nowait,則在msgsnd()執行時若是訊息佇列已
滿,則msgsnd()將不會阻塞,而會立即返回-1,並設定錯誤碼(errno)為enomsg;如果msg***為0,則在msgsnd()執行時若是訊息佇列已
滿,採取阻塞等待的處理模式。
4.接收訊息
size_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msg***);
//msqid:訊息佇列的標識碼
//msgp:指向訊息緩衝區的指標,此位置用來暫時儲存傳送和接收的訊息,結構由使用者根據訊息模板自行定義
//msgsz:訊息的大小
//msgtyp: 0--接收所有訊息型別的訊息 正數--只接收該型別的訊息
//msg***:用來指明核心程式在隊列為空的情況下所應採取的行動。如果msg***為常數ipc_nowait,則在執行msgrcv()時發現列隊為空,不做等待馬上返回-1,並設定錯誤碼為enomsg;當msg***為0時,採取阻塞等待的處理模式。
5.刪除訊息列隊
msgctl(msqid,ipc_rmid,
0);
###測試例程###
/*mq snd.c*/
#include #include #include #include #include #include #include #define msgkey 201844 //2018/04/04
struct msgstru;
int main()
} while(1)
printf("input msgtext:");
scanf("%s",str);
msg.msgtype=mtype;
strcpy(msg.msgtext,str);
//傳送訊息 //列隊滿時不阻塞,返回-1
ret=msgsnd(mqid,&msg,sizeof(struct msgstru),ipc_nowait);
if(ret < 0)
}msgctl(mqid,ipc_rmid,0); //刪除訊息列隊
return 0;
}
/*mq mqrcv.c*/
#include #include #include #include #include #include #include #include #define msgkey 201844
struct msgstru;
void childproc()
//ret=msgrcv(mqid,&msg,sizeof(struct msgstru),0,0); //列隊為空 阻塞
//只接收訊息型別為1的訊息
ret=msgrcv(mqid,&msg,sizeof(struct msgstru),1,0); //列隊為空 阻塞
printf("pid=[%d] mtype=[%ld] mtext=[%s] \n",getpid(),msg.msgtype,msg.msgtext);
}exit(0);
}int main()else if(cpid == 0)
}return 0;
}
####參考#### 訊息機制 MQ
通過訊息producer 生產者 傳送訊息,必須初始化就啟動 consumer 消費者 監控訊息佇列,接收並處理訊息,初始化就啟動 根專案pom.xml增加 4.1.0 incubating snapshotrocketmq client.version org.apache.rocketmqgro...
訊息佇列MQ
目錄 一 簡介 二 為什麼需要訊息佇列 mq 三 介紹 訊息佇列 message queuing 在電腦科學中,是一種程序間通訊或同一程序間不同執行緒的通訊方式。廣義上講訊息佇列是解決分布式系統中,各個功能模組間的資訊傳遞通訊方式。與檔案傳輸和rpc相比,訊息佇列具有更好的平台無關性,並能夠很好地支...
MQ訊息佇列
1.解耦 系統a將userid寫到訊息佇列中,系統c和系統d從訊息佇列中拿資料。這樣有什麼好處?系統a只負責把資料寫到佇列中,誰想要或不想要這個資料 訊息 系統a一點都不關心。即便現在系統d不想要userid這個資料了,系統b又突然想要userid這個資料了,都跟系統a無關,系統a一點 都不用改。系...