c linux IPC 訊息列隊MQ 學習

2021-08-18 04:49:21 字數 3693 閱讀 2584

###概念###

訊息佇列就是乙個訊息的鍊錶。可以把訊息看作乙個記錄,具有特定的格式以及特定的優先順序。對訊息佇列有寫許可權的程序

可以向其中按照一定的規則新增新訊息;對訊息佇列有讀許可權的程序則可以從訊息佇列中讀走訊息。

訊息佇列是乙個存放在核心中的訊息鍊錶,每個訊息佇列由訊息佇列識別符號標識。與管道不同的是訊息佇列存放在核心中,

只有在核心重啟(即作業系統重啟)或者顯式地刪除乙個訊息佇列時,該訊息佇列才會被真正刪除。

###標頭檔案###

#include

#include

#include

###資料結構###

1.訊息緩衝結構 (傳送、接收訊息都要以這個 資料結構模板

進行)structmsgstru;

說明:訊息文字可以為任意型別,由使用者根據需要定義,如字元陣列、結構體等;

訊息佇列中的訊息的大小是受限制的,在核心中存在巨集定義。

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一點 都不用改。系...