Linux下進程通訊消息隊列
?MQ(message queue),從字面意思上看,本質是個隊列,FIFO 先入先出,只不過隊列中存放的內容是message 而已。MQ 是在消息的傳輸過程中保存消息的容器。多用于分布式系統之間進行通信。
消息隊列與 FIFO 很相似,都是一個隊列結構,都可以有多個進程往隊列里面寫信息,多個進程從隊列中讀取信息。
1.查看消息隊列命令
??1.查看消息隊列:ipcs -q
[wbyq@wbyq ~]$ ipcs -q
--------- 消息隊列 -----------
鍵 msqid 擁有者 權限 已用字節數 消息
0xb8104ad9 1 wbyq 644 0 0
0xd2350093 2 wbyq 666 208 2
??2.查看消息隊列限制信息:ipcs -lq
[wbyq@wbyq ~]$ ipcs -lq
---------- 消息限制 -----------
系統最大隊列數量 = 32000
最大消息尺寸 (字節) = 8192
默認的隊列最大尺寸 (字節) = 16384
??3.查看消息隊列詳細信息:ipcs -q -i
[wbyq@wbyq ~]$ ipcs -q -i 2
消息隊列 msqid=2
uid=1000 gid=1000 cuid=1000 cgid=1000 模式=0666
cbytes=208 qbytes=16384 qnum=2 lspid=10177 lrpid=10175
發送時間=Thu Apr 28 11:56:08 2022
接收時間=Thu Apr 28 11:56:08 2022
更改時間=Thu Apr 28 11:49:04 2022
??4.創建消息隊列:ipcmk -Q
[wbyq@wbyq ~]$ ipcmk -Q
消息隊列 id:4
[wbyq@wbyq ~]$ ipcs -q
--------- 消息隊列 -----------
鍵 msqid 擁有者 權限 已用字節數 消息
0xb8104ad9 1 wbyq 644 0 0
0xd2350093 2 wbyq 666 208 2
0x05ae2c01 4 wbyq 644 0 0
5.刪除信號量:ipcrm -q
[wbyq@wbyq ~]$ ipcrm -q 4
[wbyq@wbyq ~]$ ipcs -q
--------- 消息隊列 -----------
鍵 msqid 擁有者 權限 已用字節數 消息
0xb8104ad9 1 wbyq 644 0 0
0xd2350093 2 wbyq 666 208 2
2.相關函數
#include
#include
#include
int msgget(key_t key, int msgflg);
函數功能:創建消息隊列
形參:key 鍵值,ftok產生
? ? ?msgflg?標志 IPC_CREAT|0666
返回值:失敗返回-1,成功返回msqid
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
函數功能: 將消息添加到隊列中
形參:msqid msgget函數返回值
???msgp 消息內容數據,一般以結構體類型填充
??????struct msgbuf {
????????????long mtype; /* 消息類型, 必須 > 0 */
????????????char mtext[1]; /消息數據/
????????????};
??????注意:struct msgbuf必須自己重寫,第一個參數long mtype必須指定,且>0,其他類型自定義
???msgsz 消息字節數,大小為:sizeof(struct msgbuf)-sizeof(mtype);
???msgflg 0當隊列滿時阻塞,直到消息寫入成功
??????IPC_NOWAIT 當隊列滿時不阻塞,立刻返回
??????IPC_NOERROR 若發送的消息大于 size 字節,則把該消息截斷,截斷部分將被丟棄,且不通知發送進程。
返回值:成功返回0,失敗返回-1;
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);
函數功能:從隊列中取出消息
形參:msqid msgget函數返回值
???msgp 存放讀取到的消息內容
???msgsz 消息字節數,大小為:sizeof(struct msgbuf)-sizeof(mtype);
???msgtyp 消息類型:
???????>0 接收對列中的第 1 個類型等于 msgtyp 的消息
???????==0 取出消息隊列中的第一條消息
???????<0 接收其類型小于或等于 msgtyp 絕對值的第 1 個最低類型消息
???msgflg 0 當隊列空時阻塞,或者消息類型不匹配時阻塞
?????? IPC_NOWAIT 不阻塞,立刻返回
?????? IPC_NOERROR 若發送的消息大于 size 字節,則把該消息截斷,截斷部分將被丟棄,且不通知發送進程。
返回值:成功返回讀取的字節數,失敗返回-1;
int msgctl(int msqid, int cmd, struct msqid_ds *buf);
函數功能:控制函數
形參:msqid msgget函數返回值
???cmd 通常為 IPC_RMID 表示刪除消息隊列。
當刪除消息隊列時,則buf填NULL即可;
3.示例
??(1)創建消息隊列,添加消息到隊列
#include
#include
#include
#include
#include
#include
#include
struct msgbuf
{
long mtype;//消息類型,必須>0
int cnt;
char buff[100];
};
int main(int argc,char *argv[])
{
if(argc!=4)
{
printf("格式:./app <消息類型> <消息數據> <消息內容>\n");
return 0;
}
key_t key=ftok("msgsnd.c", 1234);//生成鍵值
if(key==-1)
{
printf("生成鍵值失敗err=%s\n",strerror(errno));
return 0;
}
printf("key=%#x\n",key);
int msqid=msgget(key,IPC_CREAT|0666);//創建消息隊列
if(msqid==-1)
{
printf("創建消息隊列失敗err=%s\n",strerror(errno));
return 0;
}
printf("msqid=%d\n",msqid);
struct msgbuf msg;
msg.mtype=atoi(argv[1]);//消息類型
msg.cnt=atoi(argv[2]);//消息數據
strcpy(msg.buff,argv[3]);//消息內容
int msg_size=sizeof(msg)-sizeof(long);//消息大小,總大小-消息類型大小
/*添加消息到隊列*/
int size=msgsnd(msqid,&msg,msg_size,0);
if(size==-1)
{
printf("寫入消息失敗err=%s\n",strerror(errno));
}
else printf("消息寫入成功\n");
return 0;
}
??(2)從隊列中取消息
#include
#include
#include
#include
#include
#include
#include
struct msgbuf
{
long mtype;//消息類型,必須>0
int cnt;
char buff[100];
};
int main(int argc,char *argv[])
{
if(argc!=2)
{
printf("格式:./app <消息類型>\n");
return 0;
}
key_t key=ftok("msgsnd.c", 1234);//生成鍵值
if(key==-1)
{
printf("生成鍵值失敗err=%s\n",strerror(errno));
return 0;
}
printf("key=%#x\n",key);
int msqid=msgget(key,IPC_CREAT|0666);//創建消息隊列
if(msqid==-1)
{
printf("創建消息隊列失敗err=%s\n",strerror(errno));
return 0;
}
printf("msqid=%d\n",msqid);
struct msgbuf msg;
int msg_size=sizeof(msg)-sizeof(long);//消息大小
long msgtyp=atoi(argv[1]);//要寫讀取的消息類型
//從消息隊列中取數據
ssize_t size=msgrcv(msqid,&msg,msg_size,msgtyp,0);
if(size==-1)
{
printf("讀取消息失敗err=%s\n",strerror(errno));
}
else
{
printf("------------讀取消息成功size:%ld----------------\n",size);
printf("\tmtype=%ld\n",msg.mtype);
printf("\tcnt=%d\n",msg.cnt);
printf("\tbuff=%s\n",msg.buff);
}
return 0;
}
??(3)運行效果
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。
舉報投訴
-
Linux
+關注
關注
87文章
11322瀏覽量
209857 -
IPC
+關注
關注
3文章
351瀏覽量
51963 -
進程
+關注
關注
0文章
203瀏覽量
13965
發布評論請先 登錄
相關推薦
深入解析Linux程序與進程
什么是程序 一組計算機能識別和執行的指令,用于指導計算機執行特定任務或解決特定問題。程序通常由代碼、數據和資源文件組成,涉及語法、算法和數據結構。為二進制文件 什么是進程 是一個具有獨立功能的程序
JavaWeb消息隊列使用指南
用程序的通信方法,允許異步傳輸消息,并且具有存儲和轉發消息的能力。它主要解決以下問題: 異步處理 :允許系統組件異步處理任務,提高響應速度。 解耦系統 :不同系統組件之間通過消息隊列通信,降低耦合度。 流量削峰 :在高流量情況下,消息隊
深入Linux進程管理:提升效率與穩定性的關鍵方法
目錄 Linux進程管理 8.1 IO負載 8.2 實時進程監控 5.1 作業與會話 5.2 作業分類 4.1 ps 4.2pstree 4.3pgrep 4.4pidof 4.5 vmstat
一文搞懂Linux進程的睡眠和喚醒
): 進程在等待某個條件滿足(如I/O操作),可以被信號喚醒。
Linux通過內核提供的系統調用來控制進程的睡眠。常用的系統調用有:
sleep(): 使進程暫停指定的秒數。
usl
發表于 11-04 15:15
Linux用戶身份與進程權限詳解
在學習 Linux 系統權限相關的主題時,我們首先關注的基本都是文件的 ugo 權限。ugo 權限信息是文件的屬性,它指明了用戶與文件之間的關系。但是真正操作文件的卻是進程,也就是說用戶所擁有的文件
嵌入式環形隊列與消息隊列的實現原理
嵌入式環形隊列,也稱為環形緩沖區或循環隊列,是一種先進先出(FIFO)的數據結構,用于在固定大小的存儲區域中高效地存儲和訪問數據。其主要特點包括固定大小的數組和兩個指針(頭指針和尾指針),分別指向隊列的起始位置和結束位置。
深入探討Linux的進程調度器
Linux操作系統作為一個開源且廣泛應用的操作系統,其內核設計包含了許多核心功能,而進程調度器(Scheduler)就是其中一個至關重要的模塊。進程調度器負責決定在任何給定的時刻哪個進程
linux管道概述
一、進程間通信(IPC)介紹 進程間通信(IPC,InterProcess Communication)是指在不同進程之間傳播或交換信息。 IPC的方式通常有管道(包括無名管道和命名管道)、消息
如何使用linux下gdb來調試python程序
如何使用linux下gdb來調試python程序? 在Linux下,可以使用GDB(GNU調試器)來調試Python程序。GDB是一個強大的調試工具,可以幫助開發者診斷和修復程序中的錯
淺談Linux的進程
進程和程序的區別: 進程是動態的,程序是靜態的 一、進程的創建(fork()函數) int main(){ pid_t pid; pid=fork(); if(pid?????>0
Linux查看IO狀態的常用命令都有哪些呢?
介紹下Linux的3個常用I/O相關命令,解決I/O壓力過大問題時用iostat,查看磁盤的I/O狀態用iotop,查看I/O進程排名用lsof
評論