亞寵展、全球寵物產業風向標——亞洲寵物展覽會深度解析
1266
2022-05-30
前面文章介紹了linux下進程的創建,管理,陸續介紹了進程間通信的方式:管道、內存映射、共享內存等。這篇文章繼續介紹Linux的進程間通信方式消息隊列。
1. 消息隊列介紹
消息隊列通過名字字面意思理解就是隊列排隊-和平常超市買東西排隊付款一樣結構,消息隊列與FIFO很相似,都是一個隊列結構,都可以有多個進程往隊列里面寫信息,多個進程從隊列中讀取信息。但FIFO需要讀、寫的兩端事先都打開,才能夠開始信息傳遞工作。而消息隊列可以事先往隊列中寫信息,需要時再打開讀取信息。
注意事項:
消息隊列屬于順序隊列形式的結構,向隊列里寫的每一條消息,會追加到隊列后面,讀取一個就從隊列里消除一個。
寫函數不會阻塞,除非隊列里存放的消息數量已經滿了,才會導致寫阻塞。
讀函數,從隊列里讀取不到數據時,會阻塞。
查看當前系統所有的消息隊列:
[root@wbyq 20181005]# ipcs -q ------ Message Queues -------- 鍵值 消息隊列ID 使用的字節數量 隊里現存的消息數量 key msqid owner perms used-bytes messages 0x000004d3 0 root 666 65532 192 0x00003044 32769 root 666 65424 564 0x0a120534 65538 root 0 2352 21 0x0a00000f 196611 root 0 65520 2730 0xffffffff 163844 root 0 0 0
查看消息隊列的詳細信息:
[root@wbyq 20181005]# ipcs -l ------ Shared Memory Limits -------- max number of segments = 4096 max seg size (kbytes) = 4194303 max total shared memory (kbytes) = 1073741824 min seg size (bytes) = 1 ------ Semaphore Limits -------- max number of arrays = 128 max semaphores per array = 250 max semaphores system wide = 32000 max ops per semop call = 32 semaphore max value = 32767 ------ Messages: Limits -------- max queues system wide = 1736 【系統最多的消息隊列數量(最多支持同時1736個消息隊列)】 max size of message (bytes) = 65536 【單個消息的最大字節數】 default max size of queue (bytes) = 65536 【默認的單個隊列的大小65536】 默認單個隊列總字節大小為: 65535字節。 消息隊列的最大字節數量和消息的最大條數加起來的總字節數不能超過65535字節。
**System V IPC機制消息隊列相關的函數接口: ** 這里先列出所有函數,下面會詳細介紹每個函數的用法。
#include
2. 消息隊列相關函數介紹
2.1 msgget函數
函數原型:
#include
功能
msgget用于創建和訪問一個消息隊列。
參數
(1) key:是唯一標識一個消息隊列的關鍵字,如果為IPC_PRIVATE(值為0,用創建一個只有創建者進程才可以訪問的消息隊列),表示創建一個只由調用進程使用的消息隊列,非0值的key(可以通過ftok函數獲得)表示創建一個可以被多個進程共享的消息隊列;
(2) msgflg:指明隊列的訪問權限和創建標志,創建標志的可選值為IPC_CREAT和IPC_EXC,如果單獨指定IPC_CREAT,msgget要么返回新創建的消息隊列id,要么返回具有相同key值的消息隊列id;如果IPC_EXCL和IPC_CREAT同時指明,則要么創建新的消息隊列,要么當隊列存在時,調用失敗并返回-1。
/*1. 創建消息隊列*/ int msgid = msgget((key_t)1235,0666 | IPC_CREAT);
返回值
成功執行時,返回消息隊列標識值(0也是成功的)。
失敗返回-1,errno被設為以下的某個值。
EACCES:指定的消息隊列已存在,但調用進程沒有權限訪問它,而且不擁有CAP_IPC_OWNER權能 EEXIST:key指定的消息隊列已存在,而msgflg中同時指定IPC_CREAT和IPC_EXCL標志 ENOENT:key指定的消息隊列不存在同時msgflg中不指定IPC_CREAT標志 ENOMEM:需要建立消息隊列,但內存不足 ENOSPC:需要建立消息隊列,但已達到系統的最大消息隊列容量
2.2 msgsnd和msgrcy函數
原型:
#include
功能
函數msgsnd和msgrcy用來將消息添加到消息隊列中和從一個消息隊列中獲取信息。
參數
(1)msgid:指明消息隊列的ID; 通常是msgget函數成功的返回值。
(2)msgbuf:是消息結構體,它的長度必須小于系統規定的上限,必須以一個長整型成員變量開始,接收函數將用這個成員變量來確定消息的類型。必須重寫這個結構體,其中第一個參數類型不能改,其他可以自定義。
如下:
struct msgbuf { long mtype; /* type of message */ char mtext[1]; /* message text */ };
字段mtype是用戶自己指定的消息類型(通常是1—5中的任意一個數值),該結構體第2個成員僅僅是一種說明性的結構,實際上用戶可以使用任何類型的數據,就是消息內容;
(3)msgsz是消息體的大小,每個消息體最大不要超過4K; 不含消息類型占用的4個字節,即mtext的長度
(4)msgtyp有3種選項:
```cpp
msgtyp == 0 接收隊列中的第1個消息,不區分消息類型
msgtyp > 0 接收對列中的第1個類型等于msgtyp的消息
msgtyp < 0 接收其類型小于或等于msgtyp絕對值的第1個最低類型消息
```
(5)msgflg有3種選項:
0:當消息隊列滿時,msgsnd將會阻塞,直到消息能寫進消息隊列 IPC_NOWAIT:當消息隊列已滿的時候,msgsnd函數不等待立即返回 IPC_NOERROR:若發送的消息大于size字節,則把該消息截斷,截斷部分將被丟棄,且不通知發送進程。
2.3 msgctl函數
原型:
#include
功能
msgctl是消息隊列的控制函數,常用來刪除消息隊列。
參數
(1)msqid:由msgget返回的消息隊列標識符。
(2)cmd:通常為IPC_RMID表示刪除消息隊列。
(3)參數buf通常為NULL。
通過命令查看系統消息信息
(1)ipcs -q 命令查看系統的消息隊列
(2)ipcs -m查看系統的共享內存
(3)ipcs -s 查看系統的信號量集。
3. 案例代碼: 消息隊列示例1
下面兩個程序分別編譯,依次運行,不分先后順序,就可以看到效果了。
3.1 發送消息
#include
3.2 讀取消息
#include
4. 案例代碼: 消息隊列基本使用
下面兩個例子,一個例子用于創建隊列,并向隊列里寫數據,另一個例子從隊列里讀取數據。
4.1 向隊列寫入消息
程序運行需要傳入兩個額外的參數。一個是消息的類型,一個是具體的內容。
./app 1 hello ./app 2 123456789
示例代碼:
#include
4.2 從隊列讀取消息
#include
Linux 任務調度
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。